【问题标题】:What is the difference between the following 3 declarations?以下3个声明有什么区别?
【发布时间】:2017-01-30 19:59:41
【问题描述】:
var title: UILabel {
let label = UILabel()
textLabel.font = .systemFontOfSize(13)
return label
}
let title: UILabel = {
let label = UILabel()
textLabel.font = .systemFontOfSize(13)
return label
}()
lazy var title: UILabel = {
let label = UILabel()
textLabel.font = .systemFontOfSize(13)
return label
}()
如果我把'let'放在第一个,编译器会抱怨'计算属性不允许让'。好吧,有点道理。第一个和第二个之间的唯一区别是 '=' 和 '()'。那么,这是否意味着它不再是计算属性?
【问题讨论】:
标签:
swift
computed-properties
【解决方案1】:
1.
var title: UILabel {
let label = UILabel()
textLabel.font = .systemFontOfSize(13)
return label
}
这是一个read only computed property。计算属性不能是let。这些是使用其他存储/计算的属性计算的。所以他们没有自己的后备商店。因此,计算属性总是被声明为var。
2.
let title: UILabel = {
let label = UILabel()
textLabel.font = .systemFontOfSize(13)
return label
}()
这是一个stored property。这被分配了一个closure,它返回一个UILabel 对象。这个闭包在对象的实例化过程中执行,返回的UILabel对象赋值给title。
3.
lazy var title: UILabel = {
let label = UILabel()
textLabel.font = .systemFontOfSize(13)
return label
}()
这是一个lazy stored property。它还被分配了一个返回 UILabel 对象的闭包。但是这个闭包在实例化过程中并没有被执行。每当首次使用此属性时都会执行它。闭包执行后,返回的UILabel对象赋值给title。
【解决方案2】:
这是只计算得到的属性,每次尝试获取它的值时都会计算:
var title: UILabel {
let label = UILabel()
textLabel.font = .systemFontOfSize(13)
return label
}
这是由就地调用的闭包(扮演默认值角色)立即初始化的常规属性:
let title: UILabel = {
let label = UILabel()
textLabel.font = .systemFontOfSize(13)
return label
}()
这是惰性属性,仅在首次访问时被就地调用的闭包初始化:
lazy var title: UILabel = {
let label = UILabel()
textLabel.font = .systemFontOfSize(13)
return label
}()
【解决方案3】:
除了@PGDev 所说的所有内容之外,我想指出另一种编写您的第二/第三个声明的方式:
代替:
let title: UILabel = {
let label = UILabel()
textLabel.font = .systemFontOfSize(13)
return label
}()
你可以写:
let title: UILabel = {
$0.font = .systemFontOfSize(13)
return $0
}(UILabel())
和上面的完全一样,只是代码写的不一样:)