是否有必要释放ivar并同时将合成的ivar设置为零?

时间:2009-06-16 21:32:57

标签: objective-c

我已经看到代码(可能是Apple自己的示例代码)以这样的方式编写,即在dealloc中释放ivar并在viewDidUnload中设置属性。

e.g。

- (void)viewDidUnload
{
  self.navigationController = nil;
}

- (void)dealloc
{
   [_navigationController release];
}

为什么他们在两个地方?另外,为什么将nil设置为一个并释放另一个。似乎self.property = nil会处理所有事情,因为它会释放并将ivar设置为nil。

3 个答案:

答案 0 :(得分:5)

你是对的:你确实可以在任何地方做self.property = nil,包括dealloc。唯一的缺点是,如果setter方法做的事情比释放ivar更复杂,你可能最终会尝试访问已经发布的其他字段等。

至于为什么你还要在viewDidUnload中发布插座,那就是内存优化。由于您在viewDidUnload中发布的内容是在再次加载视图时将重新实现的内容,因此释放它们会在内存不足的情况下释放内存。

答案 1 :(得分:1)

Apple建议您不要在init中调用setter,尤其是dealloc例程。

这是因为此时对象只是部分设置,并且setter可能有附加到它们的观察者,或者可能被子类覆盖,否则在dealloc期间会产生不良影响,或者可能会混淆使用部分配置的对象初始化。

因此,您通常使用:

_navigationController = [[NavController alloc] init];

init例程中的样式代码

[_navigationController release];

你的dealloc中的样式代码,以及其他已知对象完全完整的代码中的setter。

有些案例需要考虑:

  • 子类覆盖setNavigationController并引用由init分配的自己的ivars。初始化崩溃。
  • 子类覆盖setNavigationController并引用在dealloc中发布的自己的ivars。在dealloc上崩溃。
  • 子类覆盖setNavigationController并重绘屏幕的某些部分。毫无意义地浪费周期,或者出现故障。
  • 同时解除分配的其他对象观察navigationController和那些观察者在dealloc期间触发

答案 2 :(得分:0)

如果您依赖于垃圾收集(在Objective-C 2.0中提供),那么将ivar设置为nil并调用release将实现相同目的。

我猜你正在查看的代码是使用release管理内存并仅将其设置为nil,以便您以后不会尝试访问不是的对象那里更长当你不依赖GC时,nil比记忆管理更能记账。