结果没有区别,只是在第二种方法中您创建了一个附加指针。在这两个版本self.cclass
中都可以很好地保存您的对象。
问题是,当您仅在第二种模式下释放对象时,在第一种模式下您将出现内存泄漏。由于retainCount
分配对象时它是 +1,因此您通过 setter 分配一个 +1 对象。这意味着,你实际上又撞上了retainCount
。现在,如果您在将对象分配给您的属性后不释放它,一旦它从那里释放,它retainCount
只会减少 1。因此让一个带有retainCount
+1 的对象在内存中浮动,永远丢失。
但是因为您已经在询问更好的版本,所以我想向您介绍惰性实例化。您可以做的是覆盖相关属性的 getter 方法并检查它是否已被分配。如果没有,则在 getter 方法中分配它,然后返回它。它看起来像这样:
- (CustomeClass*) cclass
{
if(!_cclass)
{
_cclass = [[CustomeClass alloc] init];
}
return _cclass;
}
使用此方法,您可以将 +1 保留对象分配给内部变量,从而绕过 setter 而不会增加retainCount
. 它也是内存友好的,因为你的对象只有在你真正需要它的时候才会被实例化。现在,当您将属性设置为 nil 或某个新对象时,旧对象将被正确释放。
编辑:
针对 Robert Ryan 的评论,我想添加以下内容:
这不会破坏 KVO,或干扰为您的属性分配的资格。如果你的属性被标记为assign
or weak
,那么惰性实例化就没有意义了。如果它被标记为retain
或者strong
这种实例化对象的方式非常好,特别是当它是一个你可以在配置方法中分配的属性时。
关于 KVO:在 getter 内部分配的值可以看作是初始值/默认值,因此 KVO 仍然有效。当您使用 setter 为属性分配其他内容时,它将触发。您不希望 KVO 因为默认值而触发,对吗?