雖然我們都不想我們編寫的應(yīng)用發(fā)生crash,但是crash是在所難免的。iOS系統(tǒng)對(duì)于crash有兩種處理方式,一種是由EXC_BAD_ACCESS引起的,多為內(nèi)存問(wèn)題;另一種是未被捕獲的Objective-C異常(NSException),導(dǎo)致程序向自身發(fā)送了SIGABRT信號(hào)而崩潰。我們需要了解一下如何獲取crash信息。
當(dāng)我們想在crash之前做某些操作的時(shí)候比如發(fā)送錯(cuò)誤日志到郵件或者本地保存日志的時(shí)候,我們就可以使用系統(tǒng)的一個(gè)方法去實(shí)現(xiàn)。系統(tǒng)有一個(gè)名為NSSetUncaughtExceptionHandler的方法,是用于注冊(cè)在crash時(shí)調(diào)用什么方法的。一般來(lái)說(shuō)是在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions這個(gè)方法里去注冊(cè)如
-?(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSSetUncaughtExceptionHandler(要執(zhí)行的函數(shù)名);
return YES;
}
為了方便使用我們可以定義一個(gè)類來(lái)處理異常這個(gè)類繼承NSObject,然后在這個(gè)內(nèi)部注冊(cè)異常處理函數(shù)及實(shí)現(xiàn)想要的操作。
上面的注冊(cè)換成定義的類的注冊(cè)方法即可例如下面的startLog
#import "MyCrashLog.h"
#import<sys/signal.h>
@implementation MyCrashLog
+ (void)startLog
{
dispatch_once_t one;
dispatch_once(&one, ^{
//注冊(cè)異常
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
//可添加信號(hào)量異常注冊(cè)
});
}
static void uncaughtExceptionHandler(NSException *exception)
{
/ NSLog(@"異常:%@---",exception);
截獲到異常 , 發(fā)生crash時(shí)會(huì)自動(dòng)調(diào)用此方法名稱自己可定義 但是要和注冊(cè)的名稱一樣
在此處處理異常,根據(jù)自己的需求
}
@end
上面的代碼只是注冊(cè)和處理了EXC_BAD_ACCESS異常
要處理SIGABRT信號(hào)也是如同上面一樣注冊(cè)信號(hào)異常只是函數(shù)名不一樣
在上述代碼注冊(cè)的時(shí)候添加類似
//注冊(cè)信號(hào)量
signal(SIGABRT, headleSing);
signal(SIGPROF, headleSing);
signal(SIGPROF, headleSing);
的代碼就可以注冊(cè)相應(yīng)的信號(hào)量了,其中headleSing為自定義的處理異常的信號(hào)的函數(shù)名
信號(hào)量有很多種可以按需求去注冊(cè)
到此對(duì)于異常的獲取結(jié)束