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