为什么属性默认情况下不延迟实例化?



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

我觉得我的推理中存在误解,但我不知道在哪里。我想知道为什么在可可开发中,将自动延迟实例化器作为属性的一部分并不理想。

属性是Objective-C的一个相当新的特性。大量现有代码假设 ivar 初始化为 0,因此对象获取者以 nil 开头。属性的实现是为了实现大多数人手写(或使用 Accessorizer 等工具)编写的相同类型的访问器。大多数人不是手动创建懒惰的getter,所以属性也不是以这种方式实现的。这是一个专门的问题,而不是共同的需求。

(旁注:我在这里的说法在某种程度上被atomic设为默认值这一事实所掩盖,这不是手动编写访问器的最常见方式。但它与常见的编写访问器的方式兼容,只是速度较慢,有些人确实经常编写原子访问器。懒惰是不相容的。

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

有几个类init不是指定的初始值设定项,甚至可能不是合理的(甚至合法的)初始值设定项。

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

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

如果你觉得这通常有用,你应该在 bugreport.apple.com 打开雷达。

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

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

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

最新更新