读取 NSTimer 子类的 public var valid 失败并显示 'isValid only defined for abstract class'

reading public var valid of subclass of NSTimer fails with 'isValid only defined for abstract class'

我创建了一个 NSTimer 的子class,它添加(我希望)暂停和恢复功能到 scheduledTimerWithTimeInterval 函数。

class HCTimer: NSTimer {

    var hcTimerInterval :NSTimeInterval!
    var hcTarget :AnyObject!
    var hcSelector :Selector!
    var hcUserInfo :AnyObject!
    var hcRepeats :Bool!
    var hcTimer :HCTimer!

    class func pausableScheduledTimerWithTimeInterval(ti: NSTimeInterval, target aTarget: AnyObject, selector aSelector: Selector, userInfo: AnyObject?, repeats yesOrNo: Bool) -> HCTimer {

        let hcInstanceTimer = super.scheduledTimerWithTimeInterval(ti,target: aTarget, selector: aSelector, userInfo: userInfo, repeats: yesOrNo) as! HCTimer

        hcInstanceTimer.hcTimerInterval = ti
        hcInstanceTimer.hcTarget = aTarget
        hcInstanceTimer.hcSelector = aSelector
        hcInstanceTimer.hcUserInfo = userInfo!
        hcInstanceTimer.hcRepeats = yesOrNo
        hcInstanceTimer.hcTimer = hcInstanceTimer

        return hcInstanceTimer
    }

    func pause() {
        self.invalidate()
    }

    func resume() {
        self.hcTimer = HCTimer.pausableScheduledTimerWithTimeInterval(hcTimerInterval, target: hcTarget, selector: hcSelector, userInfo: hcUserInfo, repeats: hcRepeats)
    }
}

为了在现有 viewController 中使用新的 class,我将 NSTimer 类型的现有属性替换为 HCTimer。按下按钮时启动定时器,定时器无效。

class ViewController: UIViewController {

    var severityButtonTimer = HCTimer()

    @IBAction func sortOnSeverityButtonTouchInside(sender: UIButton) {

        // Start animation if none running
        if (!severityButtonTimer.valid) {
            // Change sort order

代码编译成功,但是当函数读取 HCTimer 实例的值 'valid' 时,它失败并出现以下异常。

2016-04-08 12:03:25.234 homecaremonitor[45750:17518480] *** Terminating app     due to uncaught exception 'NSInvalidArgumentException', reason: '*** -isValid only defined for abstract class.  Define -[homecaremonitor.HCTimer isValid]!'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010f4c5d85     __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x0000000111269deb objc_exception_throw + 48
    2   CoreFoundation                      0x000000010f4c5cbd +[NSException raise:format:] + 205
    3   Foundation                          0x000000010f9477b9 NSRequestConcreteImplementation + 229
    4   Foundation                          0x000000010f95aa19 -[NSTimer(NSTimer) isValid] + 39
    5   homecaremonitor                     0x000000010ef43f78 

仍在尝试解决此问题,感谢您的帮助! 干杯, 彼得

根据 Wain

的建议,将子 class HCTimer 替换为 HCTimerWrapper
class HCTimerWrapper {

    var hcTimerInterval :NSTimeInterval!
    var hcTarget :AnyObject!
    var hcSelector :Selector!
    var hcUserInfo :AnyObject!
    var hcRepeats :Bool!
    var hcTimer :NSTimer!
    var valid : Bool {
        get {
            if hcTimer != nil  {
                return hcTimer.valid
            } else {
                return false
            }
        }
    }

    func pausableScheduledTimerWithTimeInterval(ti: NSTimeInterval, target aTarget: AnyObject, selector aSelector: Selector, userInfo: AnyObject?, repeats yesOrNo: Bool) {

        let hcInstanceTimer = NSTimer.scheduledTimerWithTimeInterval(ti,target: aTarget, selector: aSelector, userInfo: userInfo, repeats: yesOrNo)

        self.hcTimerInterval = ti
        self.hcTarget = aTarget
        self.hcSelector = aSelector
        self.hcUserInfo = userInfo!
        self.hcRepeats = yesOrNo
        self.hcTimer = hcInstanceTimer  
    }

    func pause() {
        self.hcTimer.invalidate()
    }

    func resume() {
        self.hcTimer = NSTimer.scheduledTimerWithTimeInterval(self.hcTimerInterval, target: self.hcTarget, selector: self.hcSelector, userInfo: self.hcUserInfo, repeats: self.hcRepeats)
    }
}

不要创建 NSTimer 的子类,创建一个包装器来公开您需要的功能。您的代码中已经对 hcTimer 以及它的用途和用途有些困惑(我希望这还没有变得明显),您的包装器也可以避免这种情况。

因此,您的包装器将有选择地包含一个 NSTimer 实例。永远不要调用 NSTimer() - 这实际上是您的代码当前正在做的事情。您应该没有计时器,或者您应该有一个完全创建和计划的计时器实例。