使用计时器切换布尔值?
Posted
技术标签:
【中文标题】使用计时器切换布尔值?【英文标题】:Using an Timer to switch a Boolean value? 【发布时间】:2018-02-12 22:05:11 【问题描述】:我对编码比较陌生,我正在尝试使用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]:无法识别的选择器发送到实例 0x604000646ed0 2018-02-13 10:55:35.664486+1300 HC 1[12286:466779] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[_SwiftValue SwitchBool]:无法识别的选择器发送到实例 0x604000646ed0” libc++abi.dylib:以 NSException 类型的未捕获异常终止 (lldb)谁能帮我理解为什么我会收到这个错误以及如何解决它?
【问题讨论】:
当前视图控制器是ThirdViewController
吗?顺便说一句:请遵守函数名和变量名以小写字母开头的命名约定。
你的计时器应该在某个函数内部创建,例如viewDidLoad
。
我建议你使用基于闭包的计时器,而不是基于选择器的。关闭可能只是display = !display; print(display)
@Alexander 不过,这并不能解决 OP 遇到的问题; display
属性将无法从闭包中访问,因为 self
尚不可用。
@CharlesSrstka 我知道,这就是为什么我将此评论作为评论而不是答案提供的原因。我打算将它与答案一起考虑,而不是代替它
【参考方案1】:
如果您运行此代码,您希望输出是什么?
import Foundation
class C: NSObject
var foo = type(of: self)
print(C().foo)
你期待看到C
,对吧?但是你会得到:
(C) -> () -> C
原因是当您在属性的默认值中使用self
时,self
指的是作为初始化过程的一部分创建的闭包,而不是对象本身。原因是属性默认值是在对象的init
函数完成之前计算出来的,在对象完成初始化之前你不能使用self
。所以,Objective-C 正在尝试将 SwitchBool
方法发送到闭包,而闭包当然不支持该方法。
要解决这个问题,只需将属性设为lazy
;这将导致在对象本身初始化后的某个时间初始化属性,这将使得可以使用 self
并让它实际引用您的对象,正如您从以下测试中看到的那样:
import Foundation
class C: NSObject
lazy var foo = type(of: self)
print(C().foo)
哪个输出:
C
编辑:如果有问题的对象是视图控制器,则按照@vacawama 的建议,将计时器初始化为nil
并在viewDidLoad
中创建它也是一个不错的方法。基本上,您只需要确保在对象完成初始化后的某个时间点创建计时器。
【讨论】:
感谢您详细解释的答案,现在很清楚了!谢谢以上是关于使用计时器切换布尔值?的主要内容,如果未能解决你的问题,请参考以下文章