1、什麼情況下我注意到了try catch?
@try {
NSString *a=(NSString *)[NSNullnull];
if ([aintegerValue]) {
NSLog(@"%@",[NSNullnull]);
}else{
NSLog(@"%@",[NSNullnull]);
}
NSLog(@"@try");
} @catch (NSException *exception) {
NSLog(@"%@",exception);
} @finally {
NSLog(@"@finally");
}
上面的這段代碼當運行到判斷語句後,就是不執行NSLog(@"@try");,只是輸出exception和finally。
後來我嘗試把判斷語句註釋掉了,只是輸出try和finally。
如果我們使用空去處理事情,比如把空賦值到控件的text上,空賦值到url,都會造成程序崩潰,使用了這個就會直接return。
2、下面開始講解try catch的知識。大家往下看~~~
(1)以下是最簡單的代碼寫法,其中@finally可以去掉:
1
2
3
4
5
6
7
8
9
|
@ try { // 可能會出現崩潰的代碼 } @ catch (NSException *exception) { // 捕獲到的異常exception } @finally { // 結果處理 } |
(2)在這裏舉多一具比較詳細的方法,拋出異常:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@ try { // 1 [self tryTwo]; } @ catch (NSException *exception) { // 2 NSLog(@ "%s\n%@" , __FUNCTION__, exception); // @throw exception; // 這裏不能再拋異常 } @finally { // 3 NSLog(@ "我一定會執行" ); } // 4 // 這裏一定會執行 NSLog(@ "try" ); |
tryTwo方法代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
- (void)tryTwo { @ try { // 5 NSString *str = @ "abc" ; [str substringFromIndex:111]; // 程序到這裏會崩 } @ catch (NSException *exception) { // 6 // @throw exception; // 拋出異常,即由上一級處理 // 7 NSLog(@ "%s\n%@" , __FUNCTION__, exception); } @finally { // 8 NSLog(@ "tryTwo - 我一定會執行" ); } // 9 // 如果拋出異常,那麼這段代碼則不會執行 NSLog(@ "如果這裏拋出異常,那麼這段代碼則不會執行" ); } |
爲了方便大家理解,我在這裏再說明一下情況:
如果6拋出異常,那麼執行順序爲:1->5->6->8->3->4
如果6沒拋出異常,那麼執行順序爲:1->5->7->8->9->3->4
(3)部分情況的崩潰我們是無法避免的,就算是QQ也會有崩潰的時候。因此我們可以在程序崩潰之前做一些“動作”(收集錯誤信息),以下例子是把捕獲到的異常發送至開發者的郵箱。
AppDelegate.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler); return YES; } void UncaughtExceptionHandler(NSException *exception) { /** * 獲取異常崩潰信息 */ NSArray *callStack = [exception callStackSymbols]; NSString *reason = [exception reason]; NSString *name = [exception name]; NSString *content = [NSString stringWithFormat:@ "========異常錯誤報告========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@" ,name,reason,[callStack componentsJoinedByString:@ "\n" ]]; /** * 把異常崩潰信息發送至開發者郵件 */ NSMutableString *mailUrl = [NSMutableString string]; [mailUrl appendString:@ "?subject=程序異常崩潰,請配合發送異常報告,謝謝合作!" ]; [mailUrl appendFormat:@ "&body=%@" , content]; // 打開地址 NSString *mailPath = [mailUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:mailPath]]; } |
3、注意事項:
(1)網上看到一些人catch到異常使用UIAlertView提示,個人認爲這個是不可取的,異常只適合給程序員看,提示用戶會影響用戶體驗。
(2)爲什麼iOS很少使用try catch?
第一:Apple雖然同時提供了錯誤處理(NSError)和異常處理(exception)兩種機制,但是Apple更加提倡開發者使用NSError來處理程序運行中可恢復的錯誤。而異常被推薦用來處理不可恢復的錯誤。
原文鏈接:http://www.cocoachina.com/ios/20141229/10787.html第二:try catch無法捕獲UncaughtException,而oc中大部分crash如:內存溢出、野指針等都是無法捕獲的,而能捕獲的只是像數組越界之類(這真心需要catch麼?),所以try catch對於oc來說,比較雞肋。