为什么 lazy stored properties 不能有 property observers

15 Oct 2017 by 晓晨


文档有说,

You can add property observers to any stored properties you define, except for lazy stored properties. – The Swift Programming Language (Swift 4): Properties

但文档中没有解释为什么要这样,这里我来猜猜看。

首先做个试验,

class SomeClass {
    lazy var lazyStoredProperty: Int = {
        print("execute expensive computation")
        return 42
    }()
}

let c = SomeClass()
c.lazyStoredProperty = 0

上面例子中的 lazyStoredProperty,一直没有被访问过,在最后一句中被赋值(不算访问),这个例子的执行结果是什么都不打印,也就是说它的初始值中定义的 closure 一直没有被执行。

可以看出,Swift 在处理 lazy stored properties 时,只要不访问就不求值,对其赋值也不会强制求它的初始值。这样做是合理的,尽其所能避免 lazy stored properties 的初始化求值,因为这可能是一笔很大的开销。

但想象一下,如果 lazy stored properties 允许有 property observers,那当它被赋值时,会调用两个函数,willSet 和 didSet。我们考虑一个 lazy stored property 在定义后一直没有被访问过,当它第一次被赋值时,

总的来说,让 lazy stored properties 支持 property observers 后,即便没有访问过一个 property,对其赋值也会造成其初始值求值,但是赋值操作本不需要知道原来的值,这是一笔不必要的开销。