iOS 之 APP 異常崩潰抓取
NSSetUncaughtExceptionHandler
自己用程序捕獲 crash俺榆,保存于本地
-
新建一個繼承自NSObject的類(Xcode新建一個空項目過程略)睡雇,取名字CatchCrash挚躯,在h和m文件中寫下:
void uncaughtExceptionHandler(NSException *exception)
{
// 異常的堆棧信息
NSArray *stackArray = [exception callStackSymbols];
// 出現(xiàn)異常的原因
NSString *reason = [exception reason];
// 異常名稱
NSString *name = [exception name];
NSString *exceptionInfo = [NSString stringWithFormat:@"Exception reason:%@\nException name:%@\nException stack:%@",name, reason, stackArray];
NSLog(@"%@", exceptionInfo);
NSMutableArray *tmpArr = [NSMutableArray arrayWithArray:stackArray];
[tmpArr insertObject:reason atIndex:0];
//保存到本地 -- 當然你可以在下次啟動的時候涡尘,上傳這個log
[exceptionInfo writeToFile:[NSString stringWithFormat:@"%@/Documents/error.log",NSHomeDirectory()] atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
```
添加一個繼承自UIViewcontroller的類,取名字為TestViewController。
-
注冊CatchCrash異常處理方法玛追,在Appdelegate寫下如下代碼:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
//注冊消息處理函數(shù)的處理方法
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
TestViewController *testVc = [[TestViewController alloc] init];
self.window.rootViewController = testVc;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
```
- 崩潰閃退后披诗,下次啟動 app 時上傳該 log 文件內(nèi)容至服務器即可。
增強特性
NSSetUncaughtExceptionHandler
用來做異常處理宰缤,但功能非常有限.
而引起崩潰的大多數(shù)原因如:內(nèi)存訪問錯誤颂翼,重復釋放等錯誤就無能為力了,因為這種錯誤它拋出的是Signal撵溃,所以必須要專門做Signal處理
-
定義 UncaghtExceptionHandler 類疚鲤,h 文件:
@interface UncaughtExceptionHandler : NSObject{ BOOL dismissed; } void InstallUncaughtExceptionHandler(); @end
m 文件:
void InstallUncaughtExceptionHandler() { signal(SIGABRT, MySignalHandler); signal(SIGILL, MySignalHandler); signal(SIGSEGV, MySignalHandler); signal(SIGFPE, MySignalHandler); signal(SIGBUS, MySignalHandler); signal(SIGPIPE, MySignalHandler); }
//當 app 發(fā)生錯誤產(chǎn)生如上 signal 后,即會回掉自定義函數(shù)MySignalHandler
具體實現(xiàn)略
```
-
在didFinishLaunchingWithOptions中調(diào)用該函數(shù):
- (void)installUncaughtExceptionHandler { InstallUncaughtExceptionHandler(); }
綜上2步:所有崩潰基本上沒問題了缘挑。
獲取 crash 閃退日志
-
XCode 的菜單Window->Organizer 選擇Devices -> 選中的手機 -> 點擊手機名稱左邊的箭頭
Unknown和Crash 這兩種類型分別是 內(nèi)存不夠回收內(nèi)存kill應用程序?qū)е翪rash和程序異常Crash的日志集歇。
-
打開手機 - > 設(shè)置 -> 隱私 - > 診斷與用量 - > 診斷與用量數(shù)據(jù) 這里面就是所有應用的Crash日志。
先找到存放crash的iphone系統(tǒng)路徑:var/mobile/Library/Logs/CrashReporter)找到了crash存放的路徑语淘,唉诲宇,苦于無法讀取(用程序讀出來都是nil)
通過iTunes Connect(Manage Your Applications - View Details - Crash Reports)獲取用戶的crash日志惶翻。