iOS中的Dealloc方法并将对象设置为nil [英] Dealloc method in iOS and setting objects to nil
问题描述
我有一个非常基本的问题。在我看到的一些例子中,对象只是在dealloc方法中释放。在其他情况下,对象被释放,然后设置为 nil
。是否有一个原因?在释放有利之后设置为nil?
I have a pretty basic question. In some examples I've seen, objects are just released in the dealloc method. In others, the objects are released and then set to nil
. Is there a reason for this? Is setting to nil after releasing advantageous?
推荐答案
三种解除方法
的 1。刚刚发布
- (void)dealloc {
[airplane release];
[super dealloc];
}
现在,对象引用指向一个随机位置,可能是两个中的一个事情:
Now the object reference points to a random position, which may be one of two things:
- 很可能是垃圾,因为内存位置不能被解释为对象。
- 很少会是一个不同的对象,因为内存已被重用来创建一个新对象。
a的效果通过这个指针进一步调用的方法是这三个中的一个(其中一个未定义):
The effect of a further method calls through this pointer is one of these three (which one is undefined):
-
EXC_BAD_ACCESS崩溃
因为指针指向垃圾。 - 未定义选择器崩溃,因为它指向一个没有该对象的有效对象方法。
- 一个成功的方法执行,因为新对象有一个同名的方法。
- A crash with
EXC_BAD_ACCESS
because the pointer points to garbage. - A crash with undefined selector because it points to a valid object which doesn't have that method.
- A successful method execution because the new object has a method by the same name.
的 2。发布和零
- (void)dealloc {
[airplane release], airplane = nil;
[super dealloc];
}
现在对象引用为nil,忽略任何进一步的方法调用。这可能会在您的代码中默默地导致定义但无法预见的横向效果,但至少它不会使您的应用程序崩溃。
Now the object reference is nil and any further method calls are ignored. This may silently cause a defined but unforeseen lateral effect in your code, but at least it doesn't crash your application.
3。 Nil and release
- (void)dealloc {
id temp = airplane;
airplane = nil;
[temp release];
[super dealloc];
}
这与之前相同,但它删除了发布和之间的小窗口nil对象引用指向无效对象。
This is the same as before, but it removes that small window between release and nil where the object reference points to an invalid object.
这是一个问题选择:
- 如果你喜欢崩溃只选择释放。
- 如果你宁愿忽略这个错误选择nil + release或release + nil。
- 如果您使用的是
NSZombieEnabled = TRUE
然后只是发布,请不要让僵尸为零!
- If you rather crash choose just release.
- If you rather ignore the mistake choose nil+release or release+nil.
- If you are using
NSZombieEnabled=TRUE
then just release, don't nil the zombie!
推迟选择的简单方法是使用宏。而是 [飞机发布]
你写 safeRelease(x)
其中safeRelease是你添加到.pch的以下宏目标文件:
A easy way to defer your choice is using a macro. Instead [airplane release]
you write safeRelease(x)
where safeRelease is the following macro that you add to your .pch target file:
#ifdef DEBUG
#define safeRelease(x) [x release]
#else
#define safeRelease(x) [x release], x=nil
#endif
这个宏不尊重僵尸。这是问题:当 NSZombieEnabled
是 TRUE
时,对象变成 NSZombie
。如果你没有它的对象引用,那么发送给他的任何调用都将被忽略。
This macro doesn't respect zombies. Here is the problem: when NSZombieEnabled
is TRUE
the object turns into a NSZombie
. If you nil its object reference, any call sent to him will be ignored.
要解决这个问题,这里有一个来自 Kevin Ballard 只有当 NSZombieEnabled
FALSE $时才设置指向无效编组引用的指针C $ C>。如果没有启用僵尸,这可以保证在调试期间崩溃,但不会留下僵尸。
To fix that, here is a macro from Kevin Ballard that sets the pointer to an invalid made up reference ONLY when NSZombieEnabled
is FALSE
. This guarantees a crash during debug time if zombies are not enabled, but leaves the zombies be otherwise.
#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
参考文献
Apple没有关于哪一个最好的建议。如果你想阅读社区的想法,这里有一些链接(评论主题也很棒):
References
Apple doesn't have a recommendation on which one is best. If you want to read the thoughts of the community here are some links (the comment threads are great too):
- Dealloc Jeff Lamarche
- 不要嘲笑你的代码 Daniel Jalkut
- 关于dealloc的更多信息 Jeff Lamarche
- 为零或不为零,这就是问题黄庆兰
- Objective-C中的防御性编码 Uli Kusterer
- Dealloc Jeff Lamarche
- Don’t Coddle Your Code Daniel Jalkut
- More on dealloc Jeff Lamarche
- To nil, or not to nil, that is the question Ching-Lan Huang
- Defensive Coding in Objective-C Uli Kusterer
这篇关于iOS中的Dealloc方法并将对象设置为nil的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!