一、僵尸对象问题
在MRC环境下,我们经常会碰到message sent to deallocated instance 的错误,这个错误的名称为 EXC_BAD_ACCESS , 多发生在对一个对象重复release 而过度释放的情况下,也就是所谓的僵尸对象(NSZombie Object),有时候也称作野指针问题(指针指向的是僵尸对象)。自从ios 5.0推出以后,大多数程序都切换到了ARC环境,这一类的错误也少了很多。但是他们并没有完全消失,仍然存在于代码中。下面举出几个常见的例子:
1. 委托对象未置空,常见的如UITableView,UIWebView。
这一类控件的委托是异步执行的,而且由于年代久远,他们的delegate 属性还是assign,而不是现在常用的weak。这就存在一个问题,如果页面正在加载数据,其委托对象为self , 这时候页面突然退出,委托指向的VC被释放,而tableView或者webView的delegate没有置空,就有可能触发僵尸对象问题。正确的解决方法是在页面dealloc或者viewWillDisappear的时候将delegate及时置空。
2. 注册通知后没有在dealloc中反注册。
这个情况多发生于VC中,init或viewDidload时注册了通知监听,但在dealloc时没有反注册,导致VC释放以后通知中心仍然保持着对VC的引用,也就形成了僵尸对象,当相关通知发出时,就会因为野指针而崩溃。解决方法是在dealloc 时反注册通知监听。
二、循环引用问题
1. 委托使用了strong属性,导致委托对象和被委托的对象之间形成循环引用。
2. block中引用了self,而self没有使用weak属性修饰。由于众所周知的原因,block会对他里面的对象强引用,而被他引用的对象如果又持有这个block,就会形成循环引用。
3. 定时器。由于定时器在创建时会对指定的target强引用,如果target恰好又是定时器的持有者时,就形成了循环引用。
4. JavascriptCore的循环引用。
如果你的代码中有对象(我们暂命名为JSListener)持有了 JSContext,同时该对象又实现了JSExport协议,那么就很有可能形成JSContext与JSListener的循环引用。