開發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
五:結果
六:注意是否有異常斷點,或者第三方sdk也在攔截crash,都有可能造成捕獲失敗
IOS開發筆記(5)程式異常crash捕獲與攔截
開發ios應用,解決crash問題始終是乙個難題。crash分為兩種,一種是由exc bad access引起的,原因是訪問了不屬於本程序的記憶體位址,有可能是訪問已被釋放的記憶體 另一種是未 獲的objective c異常 n ception 導致程式向自身傳送了sigabrt訊號而崩潰。其實對於...
IOS開發筆記(5)程式異常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...