何时释放实例变量

时间:2010-10-31 16:16:12

标签: objective-c cocoa-touch memory-management

基本上我有这种情况:

//in interface header 
@property(nonatomic,retain)OtherClass *otherClass;

//implementation
- (id)initWithOtherClassInstance:(OtherClass*)otherClass
{ 
    if (self != [super init])
        return self;

         self.otherClass = otherClass;

    return self;
}

- (void)dealloc
{
    //Do I need to release otherClass ?
    [otherClass release];

    [super dealloc];
}

我想知道是否应该释放一个没有显式分配的实例变量,调用new或copy?内存管理指南说我没有,但我担心的是self.otherClass = otherClass会保留实例变量,因此当我决定不在dealloc方法中释放它时会导致泄漏。

此外,在dealloc方法中释放实例变量不会产生异常,如果它被过度释放则会产生异常。

我的推理是否有意义,在这样的情况下最好的做法是什么?

4 个答案:

答案 0 :(得分:1)

是的,你确实需要发布这个,正如其他答案所示。但我发现在你通过属性设置器保留的ivar上显式调用[foo release]有点不平衡。我更喜欢在这些场景中设置self.otherClass = nil;

当然,在引擎盖下它会为你做一个释放,但它看起来更平衡和干净。

答案 1 :(得分:0)

您这样做是正确的,您提到的规则是“创建”规则。您仍然需要将所有保留与发布匹配。

答案 2 :(得分:0)

请注意

self.otherClass = otherClass

相同
[self setOtherClass:otherClass]

setOtherClass上的默认实现:看起来像

- (void) setOtherClass:(OtherClass*)other
{
  [other retain];
  [otherClass release];
  otherClass = other;
}

正如您所看到的,它会保留对象,因此您必须将其释放到某处。

如果您不喜欢没有显式alloc,new或copy的显式发布,那么您可以在dealloc中执行下一步:

- (void) dealloc
{
  [self setOtherClass:nil];
  [super dealloc];
}

答案 3 :(得分:0)

你的init方法错了。您需要将[super init]的结果分配给self。

除此之外,假设self.otherClass是一个retain属性,你所做的就是好的。如果你坚持在-init中使用属性,你应该将属性分配给dealloc中的nil,正如Ben所说,因为无论属性是分配,保留还是复制,都会发生正确的事情。

然而,

建议您不要在-init和-dealloc方法中使用访问器。这是因为子类可以覆盖它们以执行您不期望的事情,并且可以在dealloc中通知KVO观察者。所以你应该只在init中设置并保留ivar并在dealloc中释放它。