关于使用runloop避免应用闪退
runloop是OC当中最基本的一个知识点,本文主要从使用角度讲述如何在应用运行中避免因程序异常导致的应用闪退。应用闪退是很多公司的噩梦,应用闪退会导致用户的大量流失,所以控制程序的稳定性是当前很多公司技术团队的首要任务。
且抛开控制bug根源问题,为避免应用在不同环境下可能因一些不可预估的因素死掉,程序异常的处理措施便显得尤为重要了。浅显的说避免崩溃的根本原理是获取到进程的异常,从而避免异常造成的程序crash,采用苹果提供的进程监听程序代码如下:
// 监听方法1NSSetUncaughtExceptionHandler(&HandleException);// 监听方法2signal(SIGABRT, SignalHandler);signal(SIGILL, SignalHandler);signal(SIGSEGV, SignalHandler);signal(SIGFPE, SignalHandler);signal(SIGBUS, SignalHandler);signal(SIGPIPE, SignalHandler);
通过监听方法在获取到进程异常时触发相关处理:
void HandleException(NSException *exception) {
// 异常次数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从而保证应用不闪退,当然也可以告知用户选择退出应用避免因此产生的一些应用内的操作隐患,同时清空监听信息,以便之后继续循环。
- (void)makeException:(NSException *)exception {
// 一直循环,等待退出命令
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
while (!dismissed) {
for (NSString *mode in (__bridge NSArray *)allModes) { CFRunLoopRunInMode((CFStringRef)mode, 0.001, false); }
}
// 清空
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);
}
关键字:signal, sig_dfl, userinfo, runloop
版权声明
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!