使用Timer切换布尔值?

时间:2018-02-12 22:05:12

标签: swift boolean selector nstimer

我对编码比较陌生,我试图用Timer来切换布尔值。但是,我一直收到错误。这是我的代码:

var Display = true

var BoolTimer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(ThirdViewController.SwitchBool), userInfo: nil, repeats: true)

@objc func SwitchBool()
{
    if Display == true{
        Display = false
        print(Display)
    } else {
        Display = true
        print(Display)
    }
}

计时器用完时我收到此错误:

[_SwiftValue SwitchBool]: unrecognized selector sent to instance 0x604000646ed0
2018-02-13 10:55:35.664486+1300 HC 1[12286:466779] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue SwitchBool]: unrecognized selector sent to instance 0x604000646ed0'
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

有人可以帮助我理解为什么我会收到此错误以及如何解决此问题?

1 个答案:

答案 0 :(得分:2)

如果您运行此代码,您对输出的期望是什么?

SQLCMD -S .\ -Usa

您希望看到import Foundation class C: NSObject { var foo = type(of: self) } print(C().foo) ,对吧?但相反,你得到:

C

这样做的原因是,当您在属性的默认值中使用(C) -> () -> C 时,self指的是在初始化过程中创建的闭包,而不是对象本身。原因是在对象的self函数完成之前计算属性默认值,并且在对象完成初始化之前不能使用init。因此,Objective-C正在尝试将self方法发送到闭包,当然这不支持该方法。

要解决此问题,只需创建属性SwitchBool;这将导致在对象本身初始化之后的某个时间初始化属性,这样就可以使用lazy并让它实际引用您的对象,如下面的测试所示:

self

输出:

import Foundation

class C: NSObject {
    lazy var foo = type(of: self)
}

print(C().foo)

编辑:如果有问题的对象是视图控制器,则根据@vacawama的建议,将计时器初始化为C 并在nil中创建计时器也是一种很好的方法。基本上,您只需确保在对象完成初始化后的某个时刻创建计时器。