带闭包的懒惰变量
你引用的教程代码是这样的:
private lazy var variable:SomeClass = {
let fVariable = SomeClass()
fVariable.value = 10
return fVariable
}()
与此对比吧:
private var variable:SomeClass {
let fVariable = SomeClass()
fVariable.value = 10
return fVariable
}
第一个初始化variable
到新创建的SomeClass的实例,一次最多(和甚至可能没有那么多次)。第二个是只读计算变量,并在每次读取其值时创建一个新的SomeClass实例。
你的直觉是对的,那篇文章是不正确的。我猜测作者正在将计算出的属性语法与立即执行的关闭技巧混为一谈。 lazy
关键字与关闭执行多少次无关。 lazy
只是简单地导致该属性保持未初始化,直到第一次访问,此时评估等号右侧的表达式。
为了简化,此:
var myVar: MyType {
return MyType()
}
比这非常不同:
var myVar: MyType = MyType()
这是在存储类似,但具有不同的初始化语义比这:
lazy var myVar: MyType = MyType()
在第一个例子,myVar
是一个计算属性和cu中的代码每次访问myVar
时都会执行大括号。换句话说,每次访问myVar
时,都会得到一个新创建的对象。
在第二个示例中,myVar
是存储的属性,等号后面的表达式在包含该属性的类或结构的初始化过程中计算一次。
在第三个示例中,myVar
仍然是一个存储属性,但在等号(不论是初始值设定表达式,函数调用还是闭包调用)之后,对表达式的求值将被延迟,直到它被访问。
作为一个侧面说明,这行代码:
lazy var myVar: MyType = { ... }()
等同于:
func doStuffAndReturnMyType() { ... }
lazy var myVar: MyType = doStuffAndReturnMyType()
在第一个例子中的简写不是专门设计的,它只是工作,因为斯威夫特类型系统(非常棒),并将闭包视为未命名(匿名)函数。
很清楚,谢谢。 – Boon
我是否在这行中不需要拖尾括号'func doStuffAndReturnMyType(){...}()'? –
@ShadowOf好,我的错。我编辑了这篇文章来解决它。 –
我的书中的解释更好:http://www.apeth.com/swiftBook/ch03。html#_lazy_initialization – matt
谢谢 - 书的解释非常好。 – Boon