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
有什么区别?为什么我的按钮有效?
答案 0 :(得分:2)
简而言之,当您使用闭包初始化声明实例属性时,将在 return out("friendship").aggregate("x")
.out("friendship")
.where(P.without("x"))
.groupCount()
.by("email")
.order(Scope.local)
.by(Column.values, Order.decr)
.limit(Scope.local, limit);
可用之前创建该属性(在实例正确初始化之前),因此您无法访问self
。只有在实例初始化后才能访问self
实例属性,因此您可以从lazy
属性访问self
。
更长的版本:
如果您使用lazy
的闭包初始化,let button: UIButton = { return UIButton() }()
变量将在运行时以完全相同的方式处理,就像您只是将其声明为button
一样。在关闭结束时注意let button:UIButton = UIButton()
。这实际上是在初始化实例属性时立即执行闭包,这就是它实际上可以被声明为不可变的原因。由于在调用类初始化程序之前初始化实例属性,因此在属性的闭包内不能使用()
。
使用self
关键字声明变量时,只会在首次访问时对其进行评估。因此,lazy
在闭包内可用,声明self
属性,因为在创建类实例之前无法访问属性,因此在所有情况下,{ {1}}已初始化,并且在您访问懒惰媒体资源时可用。
答案 1 :(得分:2)