iOS中的Dealloc方法并将对象设置为nil

Mas*_*son 10 memory-management objective-c dealloc ios

我有一个非常基本的问题.在我看到的一些例子中,对象只是在dealloc方法中释放.在其他情况下,对象被释放然后设置为nil.是否有一个原因?释放有利后设定为零?

Jan*_*ano 23

dealloc的三种方法

1.发布

- (void)dealloc {
    [airplane release];
    [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)

现在,对象引用指向随机位置,这可能是以下两种情况之一:

  1. 很可能它是垃圾,因为内存位置不能被解释为对象.
  2. 很少会有一个不同的对象,因为内存已经被重用来创建一个新对象.

通过此指针调用另一个方法的效果是这三个中的一个(其中一个是未定义的):

  • EXC_BAD_ACCESS因为指针指向垃圾而崩溃.
  • 未定义选择器崩溃,因为它指向没有该方法的有效对象.
  • 一个成功的方法执行,因为新对象具有相同名称的方法.

2.发布并且没有

- (void)dealloc {
    [airplane release], airplane = nil;
    [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)

现在,对象引用为nil,并且忽略任何进一步的方法调用.这可能会在您的代码中默默地导致定义但无法预料的横向效果,但至少它不会使您的应用程序崩溃.

没有并且释放

- (void)dealloc {
    id temp = airplane;
    airplane = nil;
    [temp release];
    [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)

这与之前相同,但它删除了release和nil之间的小窗口,其中对象引用指向无效对象.

哪一个最好?

这是一个选择问题:

  • 如果你喜欢崩溃选择刚发布.
  • 如果你宁愿忽略错误,请选择nil + release或release + nil.
  • 如果您正在使用NSZombieEnabled=TRUE然后发布,请不要让僵尸无所适从!

宏和僵尸

推迟选择的一种简单方法是使用宏.相反,[airplane release]你写的safeRelease(x)是safeRelease是你添加到.pch目标文件的以下宏:

#ifdef DEBUG
  #define safeRelease(x) [x release]
#else
  #define safeRelease(x) [x release], x=nil
#endif
Run Code Online (Sandbox Code Playgroud)

这个宏不尊重僵尸.这里的问题是:当NSZombieEnabledTRUE对象变成NSZombie.如果您的对象引用为零,则发送给他的任何调用都将被忽略.

为了解决这个问题,这里是从宏观的凯文·巴拉德说将指针设置为无效由基准,只有当NSZombieEnabledFALSE.如果没有启用僵尸,这可以保证在调试期间崩溃,但是否则会留下僵尸.

#if DEBUG
  #define safeRelease(x) do { [x release]; if (!getenv("NSZombieEnabled")) x = (id)0xDEADBEEF; } while (0)
#else
  #define safeRelease(x) [x release], x = nil
#endif
Run Code Online (Sandbox Code Playgroud)

参考

Apple没有关于哪一个最好的建议.如果你想阅读社区的想法,这里有一些链接(评论主题也很棒):