button.addTarget(self, action: #selector(taptap), for: .touchUpInside)如何在没有lazy关键字的情况下工作?
错误地删除了lazy,并有一个闭包来初始化一个按钮,如下所示:
class MyView: UIView {
let button: UIButton = {
let button = UIButton()
button.addTarget(self, action: #selector(taptap), for: .touchUpInside)
print(self) // (Function)
// button.frame = bounds <- Cannot assign here
return button
}()
lazy var button2: UIButton = {
let button = UIButton()
print(self) // <sample.MyView ...>
return button
}()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
addSubview(button2)
addSubview(button)
button.frame = bounds
print(self) // <sample.MyView ...>
}
@objc func taptap() {
print("taptap")
}
}印刷结果是:
(Function)
<sample.MyView: 0x7f961dd09d80; frame = (67 269; 240 128); autoresize = RM+BM; layer = <CALayer: 0x6080000268a0>>
<sample.MyView: 0x7f961dd09d80; frame = (67 269; 240 128); autoresize = RM+BM; layer = <CALayer: 0x6080000268a0>>
taptap按钮闭包中的self与其他类中的self有什么不同?为什么我的扣子会起作用?
发布于 2018-03-26 13:27:05
发布于 2018-03-26 13:17:39
简而言之,当您使用闭包初始化声明实例属性时,该属性将在self可用之前(在实例被正确地失效之前)创建,因此您无法访问self。只有在实例被初始化后才能访问lazy实例属性,因此您可以从lazy属性访问lazy。
较长版本:
如果您通过let button: UIButton = { return UIButton() }()使用闭包初始化,那么button变量在运行时的处理方式将与您简单地声明为let button:UIButton = UIButton()一样。注意关闭结束时的()。这实际上是在初始化实例属性时立即执行闭包,这就是为什么它实际上可以声明为不可变的原因。由于实例属性是在调用类初始化器之前初始化的,因此在属性的闭包中不能使用self。
使用lazy关键字声明变量时,只有在首次访问变量时才会对其进行评估。因此,在闭包中可以使用self声明一个lazy属性,因为在创建类实例之前不能访问访问的属性,因此在所有情况下,self都已经初始化,并且在您访问延迟属性时已经可用。
https://stackoverflow.com/questions/49491028
复制相似问题