runloop是OC当中最基本的一个知识点,本文主要从使用角度讲述如何在应用运行中避免因程序异常致使的应用闪退。应用闪退是不少公司的噩梦,应用闪退会致使用户的大量流失,因此控制程序的稳定性是当前不少公司技术团队的首要任务。
且抛开控制bug根源问题,为避免应用在不一样环境下可能因一些不可预估的因素死掉,程序异常的处理措施便显得尤其重要了。浅显的说避免崩溃的根本原理是获取到进程的异常,从而避免异常形成的程序crash,采用苹果提供的进程监听程序代码以下:oop
// 监听方法1 NSSetUncaughtExceptionHandler(&HandleException); // 监听方法2 signal(SIGABRT, SignalHandler); signal(SIGILL, SignalHandler); signal(SIGSEGV, SignalHandler); signal(SIGFPE, SignalHandler); signal(SIGBUS, SignalHandler); signal(SIGPIPE, SignalHandler);
经过监听方法在获取到进程异常时触发相关处理:
void HandleException(NSException *exception) {code
// 异常次数 int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount); if (exceptionCount > UncaughtExceptionMaximum) { return; } // 异常信息 NSArray *callStack = [LHLExceptionHelper backtrace]; NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:[exception userInfo]]; [userInfo setObject:callStack forKey:UncaughtExceptionHandlerAddressesKey]; NSException *exceptionTemp = [NSException exceptionWithName:exception.name reason:exception.reason userInfo:userInfo]; // 个人处理 LHLExceptionHelper *exceptionHandler = [LHLExceptionHelper new]; [exceptionHandler performSelectorOnMainThread:@selector(makeException:) withObject:exceptionTemp waitUntilDone:YES];
}
记录异常次数以及获取异常信息等,最后经过获取当前的runloop避免进程crash从而保证应用不闪退,固然也能够告知用户选择退出应用避免所以产生的一些应用内的操做隐患,同时清空监听信息,以便以后继续循环。orm
(void)makeException:(NSException *)exception {进程
// 一直循环,等待退出命令
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
while (!dismissed) {rem
for (NSString *mode in (__bridge NSArray *)allModes) { CFRunLoopRunInMode((CFStringRef)mode, 0.001, false); }
}it
// 清空
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);
}io