亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS中程序異常Crash友好化處理詳解

2020-07-26 02:25:00
字體:
來源:轉載
供稿:網友

前言

前兩天接到個面試,面試官問到上線的app怎么避免閃退,首先想到的就是在編碼的時候進行各種容錯,但貌似并不是面試官想要的答案,所以表現的很糟糕。今天有時間就來整理一下,希望有所幫助。

實現效果如圖:


效果實現:


用法:

1.將截圖的中CatchedHelper文件夾拖到你的項目工程中。

2.在AppDelegate.m中找到以下方法并如下添加代碼:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch.  [UncaughtExceptionHandler installUncaughtExceptionHandler:YES showAlert:YES]; return YES;}

以上代碼就可以實現稍微友好一點的crash攔截處理。

代碼解釋:

UncaughtExceptionHandler.h主要代碼:

#import <Foundation/Foundation.h>#import <UIKit/UIKit.h>@interface UncaughtExceptionHandler : NSObject/*! * 異常的處理方法 * * @param install 是否開啟捕獲異常 * @param showAlert 是否在發生異常時彈出alertView */+ (void)installUncaughtExceptionHandler:(BOOL)install showAlert:(BOOL)showAlert;@end

UncaughtExceptionHandler.m文件主要的代碼如下:

1.發送異常信號

/* * 異常的處理方法 * * @param install  是否開啟捕獲異常 * @param showAlert 是否在發生異常時彈出alertView */+ (void)installUncaughtExceptionHandler:(BOOL)install showAlert:(BOOL)showAlert {    if (install && showAlert) {    [[self alloc] alertView:showAlert];  }    NSSetUncaughtExceptionHandler(install ? HandleException : NULL);  signal(SIGABRT, install ? SignalHandler : SIG_DFL);  signal(SIGILL, install ? SignalHandler : SIG_DFL);  signal(SIGSEGV, install ? SignalHandler : SIG_DFL);  signal(SIGFPE, install ? SignalHandler : SIG_DFL);  signal(SIGBUS, install ? SignalHandler : SIG_DFL);  signal(SIGPIPE, install ? SignalHandler : SIG_DFL);}

產生上述的signal的時候就會調用我們定義的SignalHandler來處理異常。

ps: NSSetUncaughtExceptionHandler就是iOS SDK中提供的一個現成的函數,用來捕獲異常的方法,使用方便。但它不能捕獲拋出的signal,所以定義了SignalHandler方法。

2.處理異常

void HandleException(NSException *exception) {      int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);  // 如果太多不用處理  if (exceptionCount > UncaughtExceptionMaximum) {    return;  }    //獲取調用堆棧  NSArray *callStack = [exception callStackSymbols];  NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:[exception userInfo]];  [userInfo setObject:callStack forKey:UncaughtExceptionHandlerAddressesKey];    //在主線程中,執行制定的方法, withObject是執行方法傳入的參數  [[[UncaughtExceptionHandler alloc] init]   performSelectorOnMainThread:@selector(handleException:)   withObject:   [NSException exceptionWithName:[exception name]               reason:[exception reason]              userInfo:userInfo]   waitUntilDone:YES];}

該方法就是對應NSSetUncaughtExceptionHandler的處理,只要方法關聯到這個函數,那么發生相應錯誤時會自動調用該函數,調用時會傳入exception參數。獲取異常后會將捕獲的異常傳入最終調用處理的handleException函數。

3.無法捕獲的signal處理

//處理signal報錯void SignalHandler(int signal) {    int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);  // 如果太多不用處理  if (exceptionCount > UncaughtExceptionMaximum) {    return;  }    NSString* description = nil;  switch (signal) {    case SIGABRT:      description = [NSString stringWithFormat:@"Signal SIGABRT was raised!/n"];      break;    case SIGILL:      description = [NSString stringWithFormat:@"Signal SIGILL was raised!/n"];      break;    case SIGSEGV:      description = [NSString stringWithFormat:@"Signal SIGSEGV was raised!/n"];      break;    case SIGFPE:      description = [NSString stringWithFormat:@"Signal SIGFPE was raised!/n"];      break;    case SIGBUS:      description = [NSString stringWithFormat:@"Signal SIGBUS was raised!/n"];      break;    case SIGPIPE:      description = [NSString stringWithFormat:@"Signal SIGPIPE was raised!/n"];      break;    default:      description = [NSString stringWithFormat:@"Signal %d was raised!",signal];  }    NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];  NSArray *callStack = [UncaughtExceptionHandler backtrace];  [userInfo setObject:callStack forKey:UncaughtExceptionHandlerAddressesKey];  [userInfo setObject:[NSNumber numberWithInt:signal] forKey:UncaughtExceptionHandlerSignalKey];    //在主線程中,執行指定的方法, withObject是執行方法傳入的參數  [[[UncaughtExceptionHandler alloc] init]   performSelectorOnMainThread:@selector(handleException:)   withObject:   [NSException exceptionWithName:UncaughtExceptionHandlerSignalExceptionName               reason: description              userInfo: userInfo]   waitUntilDone:YES];}

以上方法是對于捕獲不到的signal信號進行處理,列出常見的異常類型。

4.堆棧調用

//獲取調用堆棧+ (NSArray *)backtrace {    //指針列表  void* callstack[128];  //backtrace用來獲取當前線程的調用堆棧,獲取的信息存放在這里的callstack中  //128用來指定當前的buffer中可以保存多少個void*元素  //返回值是實際獲取的指針個數  int frames = backtrace(callstack, 128);  //backtrace_symbols將從backtrace函數獲取的信息轉化為一個字符串數組  //返回一個指向字符串數組的指針  //每個字符串包含了一個相對于callstack中對應元素的可打印信息,包括函數名、偏移地址、實際返回地址  char **strs = backtrace_symbols(callstack, frames);    int i;  NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];  for (i = 0; i < frames; i++) {        [backtrace addObject:[NSString stringWithUTF8String:strs[i]]];  }  free(strs);    return backtrace;}

backtrace是Linux下用來追蹤函數調用堆棧以及定位段錯誤的函數。

5.使用UIAlerView進行友好化提示

- (void)handleException:(NSException *)exception {    [self validateAndSaveCriticalApplicationData:exception];    if (!showAlertView) {    return;  }  #pragma clang diagnostic push#pragma clang diagnostic ignored "-Wdeprecated-declarations"  UIAlertView *alert =  [[UIAlertView alloc]   initWithTitle:@"出錯啦"   message:[NSString stringWithFormat:@"你可以嘗試繼續操作,但是應用可能無法正常運行./n"]   delegate:self   cancelButtonTitle:@"退出"   otherButtonTitles:@"繼續", nil];  [alert show];#pragma clang diagnostic pop    CFRunLoopRef runLoop = CFRunLoopGetCurrent();  CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);    while (!self.dismissed) {    //點擊繼續    for (NSString *mode in (__bridge NSArray *)allModes) {      //快速切換Mode      CFRunLoopRunInMode((CFStringRef)mode, 0.001, false);    }  }    //點擊退出  CFRelease(allModes);    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);    if ([[exception name] isEqual:UncaughtExceptionHandlerSignalExceptionName]) {        kill(getpid(), [[[exception userInfo] objectForKey:UncaughtExceptionHandlerSignalKey] intValue]);      } else {        [exception raise];  }}

在這里你可以做自己的crash收集操作,例如上傳服務器等。

源碼下載

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩中文理论片| **欧美日韩vr在线| 国产精品欧美激情| 欧美成人精品三级在线观看| 欧美性videos高清精品| 97色在线观看免费视频| 日韩经典中文字幕| 亚洲伊人久久综合| 久久精品影视伊人网| 97视频在线播放| 亚洲第一网中文字幕| 国语自产精品视频在线看抢先版图片| 国产精品久久久久久av下载红粉| 久久久久久久成人| 欧美日韩亚洲成人| 亚洲第一免费网站| 91精品国产亚洲| 欧美视频不卡中文| 国产精品老女人视频| 亚洲免费高清视频| 欧美精品手机在线| 欧美专区日韩视频| 国模精品视频一区二区| 91精品久久久久久久久久| 日韩一区二区三区国产| 亚洲国语精品自产拍在线观看| 国产亚洲免费的视频看| 91av网站在线播放| 欧美激情久久久| 中文字幕日韩av综合精品| 欧美激情视频一区二区| 国产91色在线| 欧美精品videos性欧美| 狠狠做深爱婷婷久久综合一区| 国产区精品在线观看| 在线日韩欧美视频| 久久夜色精品亚洲噜噜国产mv| 亚洲欧洲国产伦综合| 在线观看久久久久久| 久久久成人精品| 中文字幕日本精品| 自拍偷拍亚洲区| 亚洲自拍偷拍一区| 国产在线视频91| 久久久久久久电影一区| 粉嫩av一区二区三区免费野| 中文字幕精品影院| 久久中文字幕在线视频| 亚洲毛片在线免费观看| 久久久国产视频91| 日韩欧美一区二区在线| 亚洲伊人一本大道中文字幕| 国产一区深夜福利| 欧美久久精品午夜青青大伊人| 91伊人影院在线播放| 欧美视频专区一二在线观看| 国产一区二区三区视频在线观看| 欧美极品美女视频网站在线观看免费| 人九九综合九九宗合| 欧美国产中文字幕| 九九热这里只有精品免费看| 九色成人免费视频| 亚洲成人动漫在线播放| 国产91久久婷婷一区二区| 久久久久亚洲精品成人网小说| 成人激情电影一区二区| 欧美午夜宅男影院在线观看| 国产九九精品视频| 成人av番号网| 国产91精品高潮白浆喷水| 欧美最顶级丰满的aⅴ艳星| 久久精品免费播放| 在线看欧美日韩| 精品久久久久久中文字幕一区奶水| 狠狠色噜噜狠狠狠狠97| 国产日韩在线视频| 欧美性高跟鞋xxxxhd| 国产第一区电影| 亚洲美女又黄又爽在线观看| 午夜欧美大片免费观看| 亚洲日韩中文字幕| 国产精品99久久久久久人| 久久久精品在线| 热久久视久久精品18亚洲精品| 成人h片在线播放免费网站| 久久综合色88| 午夜精品一区二区三区在线| 欧美夫妻性生活xx| 91国产在线精品| 国产精品入口福利| 91精品国产91久久久久久| 国产视频欧美视频| 久久九九有精品国产23| 久久精品最新地址| 色婷婷av一区二区三区久久| 国产综合福利在线| 亚洲三级av在线| 欧美—级高清免费播放| 久久亚洲欧美日韩精品专区| 狠狠综合久久av一区二区小说| 欧美激情欧美狂野欧美精品| 欧美色播在线播放| 成人有码在线视频| 国产日韩欧美电影在线观看| 亚洲欧美资源在线| 亚洲国内精品在线| 国产99久久久欧美黑人| 韩国v欧美v日本v亚洲| 少妇高潮久久77777| 国产v综合v亚洲欧美久久| 黄色成人在线播放| 成人黄色av网站| 亚洲色图17p| 91黑丝高跟在线| 成人精品在线观看| 亚洲精品福利在线观看| 亚洲激情视频网站| 精品国产自在精品国产浪潮| 2021久久精品国产99国产精品| 久久久女人电视剧免费播放下载| 亚洲在线免费视频| www.久久久久久.com| 亚洲天堂网站在线观看视频| 欧美猛交免费看| 国产精品丝袜久久久久久不卡| 国内精品视频一区| 国产精品欧美日韩一区二区| 91精品国产成人| 亚洲国产97在线精品一区| 69av成年福利视频| 日韩久久精品成人| 黄色91在线观看| 国产精品偷伦免费视频观看的| 91精品国产91久久久久久不卡| 亚洲午夜未删减在线观看| 精品国产一区二区三区久久狼黑人| 国产深夜精品福利| 国产有码在线一区二区视频| 欧美夫妻性视频| 国内精品久久久久久久| 91午夜理伦私人影院| 亚洲综合中文字幕在线观看| 色婷婷综合久久久久中文字幕1| 成人欧美一区二区三区在线| 久久久免费观看| 国产精品免费看久久久香蕉| 亚洲精美色品网站| 在线观看国产精品91| 国产噜噜噜噜噜久久久久久久久| www.久久色.com| 韩国精品美女www爽爽爽视频| 一区二区三区四区精品| 中文字幕日韩在线观看| 欧美日本高清一区| 91高清免费视频| 久久久久久这里只有精品| 日韩在线播放av| 亚洲欧美在线磁力| 亚洲高清av在线| 欧美最猛性xxxxx免费| 97精品伊人久久久大香线蕉| 视频在线一区二区| 日韩欧美中文第一页| 日韩av中文字幕在线免费观看|