跟Java一样,Objective-C也有自己的捕获异常的方法。
虽然iOS有捕获异常的方法,但是实际开发中,大家用的是非常少,因为这套机制比较弱,能捕获到都是容易发现的异常,而且苹果文档也强调开发者应该做好逻辑检查,而不是依赖try-catch,所以iOS开发者使用这方法的频率远比Java开发者低很多。不过这些都是题外话,下面讲讲在ARC下,try-catch导致对象内存无法释放的情况。
我写了捕获unrecognized selector 异常的方法,如下所示:
由于obj是NSObject对象,[obj integerValue]
会抛出 unrecognized selector sent to instance
的异常。然后进入@catch的代码块,处理异常处理,但是此时obj不会再被释放了。
因为在ARC释放obj的代码执行之前,已经发生了exception,进入异常处理,这个时候是不会恢复到异常前的状态去,所以这个对象也就无法释放了。在苹果看来,如果发生异常了,说明代码有严重的错误,这个时候就应该直接停止程序了。
那么要怎么办呢?就是在文件的编译选项加上-fobjc-arc-exceptions
,这样就可以启动ARC处理异常情况下的内存管理代码,也就可以保证异常中ARC管理的对象也不会发生内存泄漏。苹果不鼓励这样做除了有上面说,还有就是因为加上-fobjc-arc-exceptions
,会生成大量使用频率很低的代码(只有在异常情况才会执行)。
除了-fobjc-arc-exceptions
之外,还有-fno-objc-arc-exceptions
。-fno-objc-arc-exceptions
就是关闭ARC异常情况下管理对象内存的功能。另外要注意Objective-C++文件, -fobjc-arc-exceptions
默认就是开启的。
参考链接:
http://clang.llvm.org/docs/AutomaticReferenceCounting.html#exceptions
why-does-try-catch-in-objective-c-cause-memory-leak