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