2011-04-04 66 views
0

可能重复:
Why setting to nil after releasing?释放后是否将对象设置为零所需?

以下哪些例子是正确的?我看到不同的程序员/应用程序以不同的方式做这件事,我只是想知道释放对象的正确方式。释放它后需要将对象设置为零吗?

API *api_handle = [[API alloc] init]; 
[api callmethod]; 
[api release]; 
api = nil; 

或者

API *api_handle = [[API alloc] init]; 
[api callmethod]; 
[api release]; 

换句话说,是否有必要设置对象为nil释放之后?如果不是,人们为什么这样做?如果是这样,那么做什么好处呢?

回答

5

这不是必需的本身但是,如果您使用的变量的范围超过-release消息,那么这是一个很好的做法。因为它阻止你不小心将消息发送给解分配的对象

1

人做到这一点。发送消息给nil总是返回0/nil,但是发送消息给一个释放对象会导致SIGSEGV处于最佳状态,其他情况下难以预料的调试行为很难。

1

取决于上下文。

  • 在dealloc?

个人选择;一些做,一些不。如果你在dealloc,该对象已经有效死亡。除了更多的取消分配之外,不应该对该对象执行任何其他方法调用。

就我个人而言,我有时会将它们设置为0x1以确保崩溃。在并发代码库中非常有用。

  • 其他地方?

将其设置为nil。如果在一个实例(一个实例变量)中有一个对象引用,该实例的生命周期与对象本身分离,那么您应该在赋值时保留该对象引用,并且在实例完成时释放它并将其释放。

这可以防止由于悬挂指针和过度版本导致的崩溃。

它也让你做if (!transientObject) transientObject = ....懒惰的初始化没有一个跟踪变量(一个布尔或东西)。

0

这不是必需的,我也不认为在释放后将局部变量设置为零是一种很好的做法,但我也不会将其标记为不良做法。

将局部变量设置为零肯定会使您远离意外的EXEC_BAD_ACCESS,但这种缺陷很容易被XCode内置静态分析器检测到,并且在运行时已被NSZombieEnabled检测到。此外,如果您修改代码并提前设置为零的引用,您将永远不会看到崩溃,并且您认为该代码段的逻辑可能不正确,因为您之后的代码没有按照您的想法执行是的,它永远不会抱怨什么。如果你已经在正确的位置释放它,为什么还要把它设置为零?如果在此之后添加更多的代码以便稍后执行某些操作,则该代码应该崩溃而不是默默跳过它,因为那样您就会知道出了问题。