但凡開發(fā)過ios程序的,都碰到過程序崩潰,而信息沒有辦法及時(shí)收集的問題。目前網(wǎng)上可以搜到的收集崩潰信息的方式一般是通過設(shè)置一個(gè)NSUncaughtExceptionHandler的回調(diào)函數(shù)進(jìn)行捕獲,然后在回調(diào)函數(shù)中把堆棧信息存到本地,再選擇一個(gè)合適的時(shí)機(jī)上傳到服務(wù)器。這種方式可以捕捉到大部分的異常,但存在一個(gè)盲區(qū),就是像數(shù)組越界等這一類的內(nèi)存錯(cuò)誤的異常是無法捕捉的。如果是在平時(shí)開發(fā)中,這種問題會(huì)及時(shí)在XCdoe中拋出來,但應(yīng)用上線后這種問題就會(huì)漏掉了。
為了解決這個(gè)問題,我研究了一下蘋果的幫助文檔,并做了一些實(shí)驗(yàn),發(fā)現(xiàn)系統(tǒng)提供的try...catch函數(shù)可以捕捉到這類異常,例如:
但是,問題是我們不能在所有代碼中都加上try...catch...,這又不是開發(fā)java程序?qū)Π伞?/p>
那么,有沒有比較巧妙的方式解決這個(gè)問題呢?
其實(shí)問題的關(guān)鍵在于能不能捕捉到exception對象,因?yàn)樗锩姘四阆胍乃行畔ⅰN蚁氲搅颂砑右粋€(gè)NSException的Category,看了看NSException的頭文件,貌似只有raiseXXX這樣的方法,那假如我們重寫raise方法,能不能捕獲到異常呢?帶著這個(gè)疑問,我試了下,果然崩潰的時(shí)候走進(jìn)了這個(gè)方法。
但是光重寫raise方法是不夠的,因?yàn)閿r截了系統(tǒng)這個(gè)方法,不會(huì)引起崩潰了。
那怎么辦呢,我又想到了AOP(通過方法置換的原理在原有方法執(zhí)行之前或之后插入一段自己的代碼),最終結(jié)果如下:
這里我用到了Aspect這個(gè)庫進(jìn)行方法置換,在exception 的raise方法執(zhí)行前,我拿到exception,然后傳給異常處理組件,進(jìn)行保存和上傳。這樣,不管是什么類型的崩潰,都能輕松的獲得他的崩潰信息。