【发布时间】:2018-05-18 00:48:39
【问题描述】:
官方文档(Swift 4.1)说:
如果您使用闭包来初始化属性,请记住其余部分 的实例尚未初始化,此时 关闭被执行。这意味着您无法访问任何其他 闭包中的属性值,即使这些属性 有默认值。您也不能使用隐式 self 属性, 或调用任何实例的方法。
所以我想我需要使用lazy var,今天我创建了一个按钮
let loginRegisterButton: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = UIColor.rgb(red: 80, green: 101, blue: 161)
button.setTitle("Register", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitleColor(UIColor.white, for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
button.addTarget(self , action: #selector(handleRegister), for: .touchUpInside)
return button
}()
所以我只是在 addTarget 方法中使用了 self ,而 XCode 似乎并没有打扰更多的程序没有任何错误。一切都很顺利。那么当我用闭包初始化属性时,为什么我可以使用 self 呢?是否有一些变化,或者我错过了什么?
【问题讨论】:
-
你代码中的目标可能是
nil,这可能起作用的原因是:"...如果你指定nil,UIKit会在响应者链中搜索响应的对象到指定的操作消息并将消息传递给该对象”(来自方法的文档) -
我很困惑,您的代码使用的是
let,但在您自己的问题中,您也在谈论lazy var。那么它是哪一个? -
@Honey OP 了解
lazy var是解决问题的正确方法。问题是为什么提供的 sn-p 工作,即使他不使用lazy var。 -
@Honey 我只是没有使用lazy var,而是使用了let
-
@N.Khasanov 您可以通过在控制器初始化期间或之后设置断点并检查
_targetActions数组(在调试器的变量视图中)来验证目标实际上是nil按钮。在此示例中,loginRegisterButton在控制器初始化期间设置,这意味着还没有self(换句话说,您不能保证此时所有内容都已初始化)。lazy解决这个问题的方式是实际分配在第一次访问时被延迟。