历史上,Objective-C中的属性通过访问方法(getter和setter)实现。在Swift中,引入了一种特殊的语法结构用于computed properties,使得创建“动态”计算其值的属性变得简单。这扩展了类型封装和代码表达能力。
问题: 并不总是方便将结果作为stored property存储,尤其是当值依赖于其他属性或不断变化时。使用计算方法会构建一个可读性较差的类型接口,隐藏了其本质。
解决方案: Computed property通过get和(如有必要)set进行定义。每当访问此类属性时,都会执行计算,而不是从内存中读取。这允许创建与对象其余状态自动同步的derived properties。
代码示例:
struct Rectangle { var width: Double var height: Double var area: Double { get { return width * height } set { // 自动更新width以适应新的area值(示例) width = sqrt(newValue / height) } } } var rect = Rectangle(width: 5, height: 2) print(rect.area) // 10 rect.area = 36 print(rect.width) // 3.0
关键特性:
可以在computed property中使用willSet/didSet吗?
不可以,willSet和didSet仅适用于stored property。对于computed property,这些观察者不工作,因为没有自动存储值。
computed property可以具有弱引用或隐式展开类型吗?
可以,computed property可以是可选的或隐式展开的。但是,做这样的属性为weak是没有意义的,因为它们不包含引用——只有计算。
在什么情况下更适合在computed property中使用private set?
访问修饰符private(set)不能应用于具有get和set的computed property,只能用于stored property。对于computed property,set可以通过private set完全私有,但这是通过set块的可用性隐式实现的。
public var area: Double { private set { ... } get { ... } }
getter的computed property每次访问时从网络加载大量数据,导致卡顿和网络过载。
优点:
缺点:
computed property基于其他stored property以最低的开销计算最终值,耗时的逻辑缓存放在单独的机制中。
优点:
缺点: