dealloc中[_x release]、[_x releae],_x=nil和,self.x = nil区别总结
dealloc中[_x release]、[_x releae],_x=nil和,self.x = nil区别
1、[_x release],_x = nil和self.x = nil等价
self.x = nil; OC中属性的设置器
设置器内部实现是这样的
- (void)setX:(id)theX{
if (_x!=theX) {
[_x release];
_x = [theX retain];
}
}
所以self.x = nil,相当于[_x = relase],_x = [nil retain];
2、[_x release]和[_x release],_x = nil区别
x 在relase后赋值nil,防止出现野指针,绝大多数的时候,没有什么明显的区别。如果你不去访问那些被释放掉的实例变量,在这两种方法间没有任何的功能方面结果的区别。但如果你访问了,也就是是说实例变量_x已经被release了,引用计数为0,此时,你再调用dealloc方法,会发生什么情况呢?
[_x release] 下,,你的程序通常下会崩溃,警告给你EXC_BAD_ACCESS,虽然你还可能最后得到一些诡异的结果(通常我们都称它为heisenbug,这种bug是诡异的出现,并且通常不好重现,以致难以修补)像是一个released对象被dealloced并且它的内存之后被你的冲虚中另一个对象利用到。在这种情况下,你可能得到一个selector not recognized异常,当消息被发送给一个被delloced完的对象,或者在一个错误的对象执行你调用的方法后,你可能仅仅得到一个异常结果。
[_x release],_x = nil下,你的程序会给一个nil值的对象发送消息并且就这么不了了之了~什么都没有发生,没有程序崩溃(no crash!!),没有其他任何实时可分辨的问题出现。
前一种方法在你正在开发,调试或者做单元测试时会更有优势。因为它会让你很容易找到问题代码。另一方面,这个方法会非常非常的糟糕,在你发布你的程序后,因为你不想你的用户在使用时遇到程序crash并且这是你可以避免的crash!
后一种方法,相反地会在开发过程中掩盖住你的bugs,但是在bugs发生的时候更温和的处理掉了,但同时你会让或多或少可能让你的程序被火球包裹,然后呈现给你的用户。
3、参考解决方案
引入宏
#if DEBUG
#define MCRelease(x) [x release]
#else
#define MCRelease(x) [x release], x = nil
#endif