为什么 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,那当它被赋值时,会调用两个函数,willSetdidSet。我们考虑一个 lazy stored property 在定义后一直没有被访问过,当它第一次被赋值时,

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