垃圾收集和保留/释放属性设置器

时间:2011-05-03 05:28:21

标签: objective-c memory-management properties garbage-collection

当阅读有关Objective-C属性的内容时,我总是被告知要制作setter(或让属性机制成为setter),如下所示:

- (void)setMyProperty:(MyClass *)newValue
{
   [newValue retain];
   [ivInstanceVariable release];
   ivInstanceVariable = newValue;
}
// or
- (void)setMyProperty:(MyClass *)newValue
{
   [ivInstanceVariable autorelease];
   ivInstanceVariable = [newValue retain];
}

我不明白。我知道retain递增对象计数器,release递减它为垃圾收集器,但如何更简单:

- (void)setMyProperty:(MyClass *)newValue
{
   ivInstanceVariable = newValue;
}

导致内存泄漏?感谢。

2 个答案:

答案 0 :(得分:2)

调用set方法时,您不知道传递的对象的保留计数是多少。它可能是1,并且可能在调用set方法后立即调用release。

set方法有责任通过调用retain来指示不应释放该对象。

对于调用release,当设置一个新值时,你的set方法应该调用旧值的release来表示它不再需要它。

最后,你应该对新值调用retain并按顺序释放旧值,因为你可能会传递与已设置的完全相同的值。

答案 1 :(得分:0)

“非原子保留”设定器的经典模式是......

- (void)setMyProperty:(MyClass *)newValue
{
if (ivInstanceVariable != newValue) {
 [ivInstanceVariable release];
 ivInstanceVariable = [newValue retain];
 }
}

if测试确保newValue不同,并且你没有旋转你的轮子调用release并保留在当前对象上。保留时额外的开销并不算太糟糕,但使用副本是另一回事......

- (void)setMyProperty:(MyClass *)newValue
{
if (ivInstanceVariable != newValue) {
 [ivInstanceVariable release];
 ivInstanceVariable = [newValue copy];
 }
}