为什么属性默认情况下懒惰地实例化?

时间:2013-10-31 03:32:38

标签: objective-c properties

到目前为止,我认为@property指令生成了一个..alloc] init]及其各自对象的getter,现在我不明白为什么这不是该语言的一部分。更糟糕的是 - 访问nil属性时也不例外。

我觉得在我的推理中某处存在误解,但我不知道在哪里。我想知道为什么将一个auto-lazy-instantiator作为属性的一部分对于Cocoa开发中的几乎所有情况都不是理想的。

2 个答案:

答案 0 :(得分:6)

属性是Objective-C的一个相当新的特性。大量现有代码假定ivars初始化为0,因此对象getter以nil开头。构建属性的实现是为了实现大多数人手工编写的相同类型的访问器(或使用Accessorizer之类的工具)。大多数人并没有手工创建懒惰的吸气剂,所以属性也没有以这种方式实现。这是一个专门的问题,而不是常见的需求。

(旁注:我的声明在某种程度上暗示atomic是默认的,这不是手动编写访问器的最常用方法。但它与编写访问器的常用方法兼容,慢一点,有些人经常写原子访问器。懒惰不兼容。)

在许多情况下,您根本不想要这种行为。我不希望-image属性自动生成空UIImage。如果没有分配,我宁愿回到nil。在许多情况下,“空”和nil之间存在显着差异。 nil标题可能表示“使用默认值”,而@""可能表示“为空”。这是一种非常常见的模式。我不经常写懒惰的访问者(但部分原因是这样做很麻烦。)

有几个类init不是指定的初始化程序,甚至可能不是一个合理的(甚至是合法的)初始化程序。

但它可能是属性的有用选项,例如:

@property (nonatomic, lazy, readwrite, strong) NSMutableArray *stuff;

如果你发现它通常很有用,你应该在bugreport.apple.com上打开雷达。

关于在ObjC中发送消息nil是合法的事实,这可以追溯到最开始。通常它非常方便(它摆脱了很多错误检查代码)。有时它是非常烦人的错误的来源(有时你仍然需要进行错误检查,并且它并不总是很明显)。但它不太可能改变。这是该语言的基本部分。

答案 1 :(得分:4)

几乎所有标准读/写属性都是从类外部分配的。在这种情况下不需要惰性实例化。该物业只保留可能已分配的任何价值。如果未分配任何值,则会获得nil。这都是正常用法。因此,正常的合成getter返回可能分配的任何值。标准的合成setter只保留指定的值,负责正确的内存管理和一些KVO。

如果您希望getter返回一些内部的延迟加载值,那么这是一种特定于您对该属性的需求的行为。您需要实现自己的自定义getter来提供该行为。这远比大多数简单属性少见。