NSTimer、setNeedsDisplay、无法识别的选择器问题

NSTimer, setNeedsDisplay, unrecognized selector issues

此应用程序的逻辑正常运行,但计时器运行不正常。我有三个文件:ViewController.Swift、clock.swift 和 clockstylekit.swift.

updateTime(),位于 clock.swift 文件中,提取时间,将其分解为多个部分,returns 小时、分钟和秒,并调用 drawRect 重新绘制时间的可视化表示.

import UIKit
import Foundation

    class timeUpdate: UIView {

        func updateTime() -> (Int, Int, Int) {
            var date:NSDate = NSDate()
            var calendar:NSCalendar = NSCalendar.currentCalendar()
            var components:NSDateComponents = calendar.components(NSCalendarUnit.CalendarUnitHour | NSCalendarUnit.CalendarUnitMinute | NSCalendarUnit.CalendarUnitSecond, fromDate: date)

            var hour = components.hour
            var minute = components.minute
            var second = components.second

            setNeedsDisplay()
            return (hour, minute, second)
        }
    }

同样位于 clock.swift 文件中的 drawRect() 方法将时间组件绘制到 UIView:

class clock: UIView {

    override func drawRect(rect: CGRect) {

        let (hour, minute, second) = timeUpdate().updateTime()

        switch hour {

        case 0:

            ClockStyleKit.drawCanvas0()

        case 01, 13:
            ClockStyleKit.drawCanvas0()
            ClockStyleKit.drawCanvas01()

        .....etc etc
     }
}

这是我正在使用的定时器:

var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateTime"), userInfo: nil, repeats: true)

当我将其放入 ViewController viewDidLoad 函数时,出现无法识别的选择器错误。当我将它放入我的 clock.swift 文件中的一个函数中时,我可以毫无错误地进行编译,时间会正确更新,但它只运行一次并且不会更新。这个计时器应该去哪里?

如果 var timer = NSTimer... 代码在您的 ViewController 函数中,那么 self 将成为 ViewController。在您的计时器中,您将目标设置为等于 self,因此它将在您的 ViewController 中查找名为 updateTime 的方法,但它不存在,因为它在 [=16] =] class。另外,您的选择者的签名是错误的。您正在调用 updateTime(),但它想调用一个参数为 NSTimer 的选择器,该参数 returns 为空,因此您需要调用具有此签名的例程:

func firedTimerMethod(timer: NSTimer)

重新阅读 Xcode 中文档中对 NSTimer 的描述。

您的计时器函数的签名有误。根据文档,选择器必须具有以下签名:

- (void)timerFireMethod:(NSTimer *)timer

因此您需要创建一个计时器方法,例如:

 func updateTime(time:NSTimer) {
    // your code here
 }

然后使用Selector(updateTime:)

调用它

我建议您只需让计时器请求时钟显示刷新,并在显示代码中计算显示时间之前的时间。

我要做的就是将我的计时器放在我的 viewcontroller 中,如下所示:

class ViewController: UIViewController {

    var timer = NSTimer()    
    override func viewDidLoad() {
        super.viewDidLoad()

         self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("firedTimerMethod:"), userInfo: nil, repeats: true)

    }

    @objc func firedTimerMethod(timer: NSTimer) {
        println("firedTimerMethod fired")
        let clockView = self.view as! clock
        clockView.setNeedsDisplay()
    }
}

计时器的选择器函数需要 NSTimer 参数,@objc,我不得不将变量转换为时钟 class。完成这些操作后,drawRect 现在会正确更新计时器运行的每一秒。感谢大家的帮助,各种线索最终让我走上了正轨。