跟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