2016-11-29 59 views
2

我想在代碼中任何地方出現異常時顯示警報。從項目中的任何位置拋出異常

沒有封閉可能會拋出異常的代碼。

每次當異常occures它顯示在主類的錯誤。那可以從那裏處理嗎?

這是使用拋出異常IM的正常方式:

@try { 
// code that may throw exception 

} 
@catch (NSException * e) { 
    // show alert 
} 
@finally {  
} 
+4

您是否在尋找用於測試目的這樣做,或者實際上在你的應用程序出貨?因爲如果你正在測試,Xcode有一種方法來設置異常拋出的斷點(這可能是你想要的)。如果您希望在真實應用中發佈這個功能,我會強烈建議您不要這樣做 - 這會隱藏真實的錯誤和異常,否則這些錯誤和異常會在崩潰報告中報告給您;通過捕捉異常並向用戶顯示,您完全失去了這些信息。 –

回答

-1

我在main.m中添加了異常處理代碼。

int main(int argc, char * argv[]) { 
      @try { 
       @autoreleasepool { 
       return UIApplicationMain(argc, argv, nil, NSStringFrom 

Class([AppDelegate class])); 
      } 

     } @catch (NSException *exception) { 

      NSLog(@"exception"); 
     } 
    } 

它現在工作。

+0

有了這段代碼,應用程序是否仍然崩潰? – GeneCode

+1

不會,它會進入異常@ catch塊 – Saranjith

+1

我以前做過這件事,應用程序崩潰了,但是自從異常被捕獲後,進程本身沒有。執行catch之後,您可能只會有一個黑屏。 @Umesh Verma的方法是處理這個問題的傳統方式。 Crashlytics和其他大牌使用與Umesh相同的方法。 – Jake

4

導航到斷點面板在Xcode中,單擊左下角「加號」按鈕添加新的斷點,然後執行以下操作:

enter image description here

構建和運行項目時,Xcode會帶給你到異常投行。

+0

我需要使用此功能發佈應用程序。不用於調試目的 – Saranjith

8

但是,我找到了一個有效的解決方法 - 創建我自己的異常處理程序(這對其他原因也很有用)。首先,創建一個函數,將處理錯誤,並輸出到控制檯(以及你想用它做其他)

void uncaughtExceptionHandler(NSException *exception) { 
     NSLog(@"CRASH: %@", exception); 
     NSLog(@"Stack Trace: %@", [exception callStackSymbols]); 
     // Internal error reporting 
    } 

接下來,異常處理程序添加到您的應用程序代理:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    { 
     NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); 
     // Normal launch stuff 
    } 

如果這行不通,那麼只有兩個可能的原因:

有東西覆蓋您的通話NSSetUncaughtExceptionHandler(只能有一個爲您的整個應用程序的處理程序)。例如,一些第三方庫設置了自己的uncaughtExceptionHandler。因此,請嘗試在didFinishLaunchingWithOptions函數的END處設置它(或者選擇性地禁用第三方庫)。或者更好的是,在NSSetUncaughtExceptionHandler上設置一個符號斷點,以快速查看誰在調用它。你可能想要做的是修改你當前的一個,而不是添加另一個。 你實際上沒有遇到異常(例如,EXC_BAD_ACCESS不是例外)

4

如果我理解正確的問題,看來你正在尋找來處理你的代碼可能已被用戶作用驅動錯誤的好辦法(如無效數據,在形式失蹤領域,等等。)。

要做到這一點,最好的辦法是使用NSError,而不是NSExceptionNSError通常用於傳遞期待一個可能的錯誤,其中,作爲NSException更所以是出乎意料的,或由顯影劑引起,因此,應該在開發期間被處理的錯誤碼不同接口之間的信息。

要在你的代碼的任何地方出現的警報,你可以一個方法添加到您的應用程序委託,並使用target-action沿着你的錯誤傳遞。這可能是這樣的:

@protocol DLErrorPresentation <NSObject> 
- (void)showAlertWithError:(NSError*)error sender:(id)sender 
@end 

- (void)showAlertWithError:(NSError*)error sender:(id)sender { 
// Your alert presentation code 
} 

// In some view controller or view: 
NSError* error; 
if(![self somethingThatMayError:error]) { 
    id<DLErrorPresentation> responder = [self targetForAction:@selector(showAlertWithError:sender:); 
    [responder showAlertWithError:error sender:self] 
} 

爲了提供額外的背景下,這裏是蘋果公司稱,他們的文檔中的例外:

你應該保留使用異常的編程或意外的運行時錯誤,如出邊界集合訪問,試圖改變不可變對象,發送無效消息以及失去與窗口服務器的連接。在創建應用程序時而不是在運行時,您通常會處理這些異常類型的異常。

代替異常,錯誤對象(NSError)和Cocoa錯誤傳遞機制是在Cocoa應用程序中傳達預期錯誤的推薦方式。

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Exceptions/Exceptions.html#//apple_ref/doc/uid/10000012i

雖然異常在許多編程環境通常用於控制編程流程或表明的錯誤,這樣在可可和可可觸摸應用程序不使用異常。相反,您應該使用方法或函數的返回值來指示發生了錯誤,並在錯誤對象中提供有關該問題的信息。

https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/ExceptionHandling.html#//apple_ref/doc/uid/TP40008195-CH18-SW1