淺談第三方 SDK 和自定義 crash 上報衝突問題
簡介
在開發iOS
應用,解決Crash
問題始終是一個難題。Crash
分為兩種,一種是由EXC_BAD_ACCESS
引起的,原因是訪問了不屬於本程序的記憶體地址,有可能是訪問已被釋放的記憶體;另一種是未被捕獲的Objective-C
異常,導致程式向自身傳送了UNIX
訊號而崩潰。對於這兩種Crash
的捕獲,精準高效的收集線上崩潰可以幫助我們更好的解決問題和提高使用者體驗,現在比較成熟的崩潰收集工具也比較多,比如:友盟統計,Crashlytics
,騰訊的bugly
等等。也可以通過自定義crash
上報,來處理異常。
問題
但是當自定義crash
上報收集工具與第三方crash
收集工具共存的時候,發現自定義crash
上報收集工具,不能捕獲到exception
。
原因
/* Set the uncaught exception handler */ NSSetUncaughtExceptionHandler(&uncaught_exception_handler);
不管是第三方還是自定義的上報收集工具,一般會常用註冊ExceptionHandler
的方式,來捕獲exception
,但是並沒有將異常進行丟擲,所以,當工程中使用了第三方上報收集工具進行異常統計的時候,我們自己寫的異常捕獲有可能會失效。
解決方法
首先儲存第三方的ExceptionHandler
,然後在設定自己處理exception
的ExceptionHandler
,在自己的ExceptionHandler
處理完異常之後,再將異常塞給之前的第三方ExceptionHandler
。
static NSUncaughtExceptionHandler *_previousHandler; // 儲存第三方處理異常的 handler _previousHandler = NSGetUncaughtExceptionHandler(); // 設定自己處理異常的 handler NSSetUncaughtExceptionHandler(&UncaughtExceptionHandlerYourself);
處理自己的異常
void UncaughtExceptionHandlerYourself (NSException *exception) { }
處理完自己的邏輯之後就需要把exception
賦值給我們之前儲存的handler
,否則第三方就無法統計到崩潰的資料。
_previousHandler(exception);
總結,通過這種方法,第三方和我們上報收集工具,都可以正常的收集崩潰資料。第三方上報收集工具捕獲到異常,再處理完自己的邏輯後,將exception
拋了出來,我們自己的崩潰日誌收集庫收到第三方上報收集工具丟擲來的exception
,處理完自己的邏輯後再將exception
拋給第三方上報收集工具的handler
。