IOS開發筆記(5)程式異常crash捕獲與攔截

2021-06-20 11:16:30 字數 4248 閱讀 5836

開發ios應用,解決crash問題始終是乙個難題。crash分為兩種,一種是由exc_bad_access引起的,原因是訪問了不屬於本程序的記憶體位址,有可能是訪問已被釋放的記憶體;另一種是未**獲的objective-c異常(n***ception),導致程式向自身傳送了sigabrt訊號而崩潰。其實對於未捕獲的objective-c異常,我們是有辦法將它記錄下來的,如果日誌記錄得當,能夠解決絕大部分崩潰的問題。這裡對於ui執行緒與後台執行緒分別說明。

一:在.h檔案中編寫

[plain]view plain

copy

@inte***ce uncaughtexceptionhandler : nsobject  

@end  

void handleexception(n***ception *exception);  

void signalhandler(int signal);  

void installuncaughtexceptionhandler(void);  

二:在.m檔案編寫

[plain]view plain

copy

#import "uncaughtexceptionhandler.h"  

#include 

#include 

//  

nsstring * const uncaughtexceptionhandlersignalexceptionname = @"uncaughtexceptionhandlersignalexceptionname";  

nsstring * const uncaughtexceptionhandlersignalkey = @"uncaughtexceptionhandlersignalkey";  

nsstring * const uncaughtexceptionhandleraddresseskey = @"uncaughtexceptionhandleraddresseskey";  

volatile int32_t uncaughtexceptioncount = 0;  

const int32_t uncaughtexceptionmaximum = 10;  

const nsinteger uncaughtexceptionhandlerskipaddresscount = 4;  

const nsinteger uncaughtexceptionhandlerreportaddresscount = 5;  

@implementation uncaughtexceptionhandler  

+ (nsarray *)backtrace  

free(strs);  

return backtrace;  

}  - (void)alertview:(uialertview *)analertview clickedbuttonatindex:(nsinteger)anindex  

else if (anindex==1)   

}    

- (void)handleexception:(n***ception *)exception  

}  cfrelease(allmodes);  

nssetuncaughtexceptionhandler(null);  

signal(sigabrt, sig_dfl);  

signal(sigill, sig_dfl);  

signal(sigsegv, sig_dfl);  

signal(sigfpe, sig_dfl);  

signal(sigbus, sig_dfl);  

signal(sigpipe, sig_dfl);  

if ([[exception name] isequal:uncaughtexceptionhandlersignalexceptionname])  

else  

}  @end  

void handleexception(n***ception *exception)  

nsarray *callstack = [uncaughtexceptionhandler backtrace];  

nsmutabledictionary *userinfo =  

[nsmutabledictionary dictionarywithdictionary:[exception userinfo]];  

[userinfo  

setobject:callstack  

forkey:uncaughtexceptionhandleraddresseskey];  

[[[[uncaughtexceptionhandler alloc] init] autorelease]  

performselectoronmainthread:@selector(handleexception:)  

withobject:  

[n***ception  

exceptionwithname:[exception name]  

reason:[exception reason]  

userinfo:userinfo]  

waituntildone:yes];  

}  void signalhandler(int signal)  

nsmutabledictionary *userinfo =  

[nsmutabledictionary  

dictionarywithobject:[nsnumber numberwithint:signal]  

forkey:uncaughtexceptionhandlersignalkey];  

nsarray *callstack = [uncaughtexceptionhandler backtrace];  

[userinfo  

setobject:callstack  

forkey:uncaughtexceptionhandleraddresseskey];  

[[[[uncaughtexceptionhandler alloc] init] autorelease]  

performselectoronmainthread:@selector(handleexception:)  

withobject:  

[n***ception  

exceptionwithname:uncaughtexceptionhandlersignalexceptionname  

reason:  

[nsstring stringwithformat:  

nslocalizedstring(@"signal %d was raised.", nil),  

signal]  

userinfo:  

[nsdictionary  

dictionarywithobject:[nsnumber numberwithint:signal]  

forkey:uncaughtexceptionhandlersignalkey]]  

waituntildone:yes];  

}  void installuncaughtexceptionhandler(void)    

[plain]view plain

copy

installuncaughtexceptionhandler();  

self.window = [[[uiwindow alloc] initwithframe:[[uiscreen mainscreen] bounds]] autorelease];  

self.viewcontroller = [[[viewcontroller alloc] initwithnibname:@"viewcontroller" bundle:nil] autorelease];  

self.window.rootviewcontroller = self.viewcontroller;  

[self.window makekeyandvisible];  

return yes;  

}  

四:最後的測試

[plain]view plain

copy

- (ibaction)onclcko:(id)sender   

五:結果

IOS開發筆記(5)程式異常crash捕獲與攔截

開發ios應用,解決crash問題始終是乙個難題。crash分為兩種,一種是由exc bad access引起的,原因是訪問了不屬於本程序的記憶體位址,有可能是訪問已被釋放的記憶體 另一種是未 獲的objective c異常 n ception 導致程式向自身傳送了sigabrt訊號而崩潰。其實對於...

IOS開發筆記 程式異常crash捕獲與攔截

開發ios應用,解決crash問題始終是乙個難題。crash分為兩種,一種是由exc bad access引起的,原因是訪問了不屬於本程序的記憶體位址,有可能是訪問已被釋放的記憶體 另一種是未 獲的objective c異常 n ception 導致程式向自身傳送了sigabrt訊號而崩潰。其實對於...

iOS開發筆記

1.預設快取策略下 useprotocolcachepolicy 對於靜態資源的訪問,請求頭會自動帶上 if none match if modified since 快取方面,響應頭帶有 last modified etag 兩個字段 儘管charles抓包結果為304,但是 urlsession...