iOS程序異常crash捕獲與攔截
對于iOS應(yīng)用try-catch并不能捕獲所有異常,也就是說有時(shí)候我們加上了try-catch可是程序還是會Crash,目前我所總結(jié)有兩種:一種是由EXC_BAD_ACCESS引起的,原因是訪問了不屬于本進(jìn)程的內(nèi)存地址,有可能是訪問已被釋放的內(nèi)存;另一種是未被捕獲的Objective-C異常(NSException),導(dǎo)致程序向自身發(fā)送了SIGABRT信號而崩潰。其實(shí)對于未捕獲的Objective-C異常,我們是有辦法將它記錄下來的,如果日志記錄得當(dāng),能夠解決絕大部分崩潰的問題。下面對于UI線程與后臺線程分別說明。
傳統(tǒng)的捕獲異常的方式中所熟知try-catch-finally,但有些時(shí)候一些iOS系統(tǒng)的api是原生的C語法格式例如:sqlite3.c,UnGzip.c這些是不支持OC或者C++的try-catch機(jī)制即使有異常也是捕獲不到,或者是一些內(nèi)存的問題等在try里面還是會無情的Crash。
iOSSDK中提供了一個(gè)現(xiàn)成的函數(shù)NSSetUncaughtExceptionHandler用來做異常處理,但功能非常有限,而引起崩潰的大多數(shù)原因如:內(nèi)存訪問錯(cuò)誤,重復(fù)釋放等錯(cuò)誤就無能為力了,因?yàn)檫@種錯(cuò)誤它拋出的是Signal,所以必須要專門做Signal處理。代碼如下
通過上圖的操作我們就完成了iOS SDK給我們提供的捕捉異常處理,我們只需要在HandleException方法中紀(jì)錄我們的異常信息即可。但這僅僅是捕獲一般的OC異常信息,對于Signal異常信號我們?nèi)匀粺o法捕獲到,此時(shí)我們就需要去注冊一些Signal信號來幫助我們捕獲Signal異常。首先介紹一下Signal信號:
signal。既信號量,ios是Linux內(nèi)核,在程序發(fā)生未捕獲異常時(shí),程序會向自身發(fā)送信號(SIGABRT、SIGBUS、SIGHUP等。。。),然后程序直接閃退。。。有時(shí)候這是無可避免的。作為一款優(yōu)秀的軟件,必須要有異常報(bào)告模塊,讓用戶給你發(fā)送異常報(bào)告信息。這樣才能根據(jù)異常信息來做相應(yīng)地Debug工作。在iOS SDK
signal.h里面有31種信號方式這里不做一一解釋。
下面說一下怎么注冊這些信號量來幫助我們記錄到異常信息。代碼如下:
上圖中的signal(SIGHUP, void(*)(int));方法為iOS signal.h中的注冊信號量的方法其中第二個(gè)參數(shù)為收到信號的回調(diào)函數(shù),我們通過這個(gè)回調(diào)函數(shù)可以根據(jù)我們的需求做一些處理。
小結(jié):try-Catch只能幫助我們攔截一些bug或者幫助我們提供一些錯(cuò)誤信息,要從根本上解決程序的問題還需要不斷的調(diào)試,優(yōu)化。
作者:Olivia_Zqy