很多时候,开发的APP会存在在真机上出现闪退和崩溃的问题,如果捕获到这些异常,就以快速定位问题所在,所以这里记录下如何捕获和处理方法。
总的核心思想是:
1.让程序知道出现闪退和崩溃的问题时,该调用什么
2.对闪退和崩溃问题进行处理
key point:
ios里面的崩溃和闪退分两种情况,一种是未捕获的异常,通常是一些NSXXXXException这种,这种异常,可以通过NSSetUncaughtExceptionHandler 函数来进行异常处理。还有一种,内存访问错误,重复释放等这些错误造成的,就不是exception了,而是抛出Signal,这就需要做专门的Signal处理。
1.让程序知道出现闪退和崩溃的问题时,该调用什么:
//在AppDelegate.m里面的didFinishLaunchingWithOptions方法里面注册一下(didFinishLaunchingWithOptions方法在app启动时总会调用,所以在这里面注册)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//对应第一种情况,如果有未捕获的异常,通过NSSetUncaughtExceptionHandler方法,来向程序注册,当这种情况时,就调用HandleException方法来进行处理
NSSetUncaughtExceptionHandler(&HandleException);
//对应第二种情况,抛出了Signal的时候,就调用SignalHandler方法处理
//第一个参数,表示抛出的Signal,当系统抛出SIGABRT这个Signal的时候,就调用SignalHandler方法进行处理
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);
XXXXXXXXX
}
2.对闪退和崩溃问题进行处理:
//HandleException方法
volatile int32_t UncaughtExceptionCount = 0;
const int32_t UncaughtExceptionMaximum = 10;
void HandleException(NSException *exception)
{
//我也不明白到玩意到底啥意思
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
{
return;
}
//获得关于exception的信息
NSArray *stackArray = [exception callStackSymbols];
NSString *reason = [exception reason];
NSString *name = [exception name];
NSString *errorMessage = @"";
errorMessage = [errorMessage stringByAppendingFormat:@"App Crash error:name=%@;reason=%@;stack=%@",name,reason,[stackArray componentsJoinedByString:@";"]];
//处理exception或者发送mail或者上传得到的exception信息
}
//SignalHandler方法
void SignalHandler(int signal)
{
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
{
return;
}
//处理signal或者发送mail或者上传得到的signal信息
}
//得到backtrace的内容,就相当于exception的详细log
const NSInteger UncaughtExceptionHandlerSkipAddressCount = 4;
const NSInteger UncaughtExceptionHandlerReportAddressCount = 5;
+ (NSArray *)backtrace
{
void* callstack[128];
int frames = backtrace(callstack, 128);
char **strs = backtrace_symbols(callstack, frames);
int i;
NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
for (
i = UncaughtExceptionHandlerSkipAddressCount;
i < UncaughtExceptionHandlerSkipAddressCount +
UncaughtExceptionHandlerReportAddressCount;
i++)
{
[backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
}
free(strs);
return backtrace;
}