4、NSException拋出異常&NSError簡單介紹

Crash我們不得不面對的問題,但是好多人在遇到Crash的時候都無從下手,很多的時候都是憑著感覺找問題。今天我做了5篇文章來幫助我們更加清晰的認清iOS中的Crash

想要了解更詳細的內(nèi)容可以點擊這里

NSException1.png

上面這張圖想必大家都不陌生吧
其實控制臺輸出的日志信息就是NSException產(chǎn)生的,一旦程序拋出異常,程序就會崩潰,控制臺就會有這些崩潰日志。

這個類是專門表示異常的,Cocoa框架要求所有的異常都是它或者是它子類的實例,當(dāng)實例調(diào)用raise或者throw方法時就會出現(xiàn)我們?nèi)缟蠄D之類的崩潰,并給出它的一些相關(guān)信息。下面介紹NSException對象的幾個重要的屬性。

  • name : 用于唯一地識別異常的短字符串。名稱是必需的
  • reason:一個更長的包含造成異常原因的“人類可讀的”字符串。原因是必需的。
  • userInfo:主要當(dāng)異常被拋出時,返回原因等信息的一個字典。

異常處理

NSException.png

上面這幅圖是官網(wǎng)給出的一個圖

  • @try - 定義一個代碼塊,它是一個異常處理域:可能引發(fā)異常的代碼。
  • @catch()- 定義一個包含代碼的塊,用于處理塊中拋出的異常@try。參數(shù)@catch是本地拋出的異常對象; 這通常是一個NSException對象,但也可以是其他類型的對象,例如NSString對象。
  • @finally - 定義一個相關(guān)代碼塊,無論是否拋出異常,隨后都會執(zhí)行該代碼塊。
  • @throw - 拋出異常; 這個指令的行為幾乎與raise方法相同NSException。您通常會拋出NSException對象

最簡單的使用

//異常的名稱
NSString *exceptionName = @"異常的名稱";
//異常的原因
NSString *exceptionReason = @"我異常的原因";
//異常的信息
NSDictionary *exceptionUserInfo = nil;

NSException *exception = [NSException exceptionWithName:exceptionName reason:exceptionReason userInfo:exceptionUserInfo];

NSString *test = @"test";

if ([test isEqualToString:@"test"]) {
//拋異常
@throw exception;
}
NSException2.png

系統(tǒng)也給我們提供了很多種異??梢灾苯邮褂?/p>

//系統(tǒng)提供了很多異??梢灾苯邮褂?FOUNDATION_EXPORT NSString * const NSGenericException;
FOUNDATION_EXPORT NSString * const NSRangeException;
FOUNDATION_EXPORT NSString * const NSInvalidArgumentException;
FOUNDATION_EXPORT NSString * const NSInternalInconsistencyException;

FOUNDATION_EXPORT NSString * const NSMallocException;

FOUNDATION_EXPORT NSString * const NSObjectInaccessibleException;
FOUNDATION_EXPORT NSString * const NSObjectNotAvailableException;
FOUNDATION_EXPORT NSString * const NSDestinationInvalidException;

FOUNDATION_EXPORT NSString * const NSPortTimeoutException;
FOUNDATION_EXPORT NSString * const NSInvalidSendPortException;
FOUNDATION_EXPORT NSString * const NSInvalidReceivePortException;
FOUNDATION_EXPORT NSString * const NSPortSendException;
FOUNDATION_EXPORT NSString * const NSPortReceiveException;

FOUNDATION_EXPORT NSString * const NSOldStyleException;


用途

  • 1、可以用來捕獲異常,防止程序的崩潰。當(dāng)你意識到某段代碼可能存在崩潰的危險,那么你就可以通過捕獲異常來防止程序的崩潰
  • 2、分類(category) + runtime + 異常的捕獲 來防止Foundation一些常用方法使用不當(dāng)而導(dǎo)致的崩潰。其原理就是利用category、runtime來交換兩個方法,并且在方法中捕獲異常進行相應(yīng)的處理

數(shù)組越界這是一個十分常見的問題,這里我們就來簡單的解決一下數(shù)組越界問題

NSMutableArray *arr = [NSMutableArray arrayWithObject:@[@"1"]];
NSLog(@"%@",arr[2]);

NSLog(@"%s",__func__);

上面的代碼肯定會出現(xiàn)下面這個錯誤


NSException3.png

但是我們可以在數(shù)組越界的時候進行一個NSException處理,那么我們的程序就不會閃退

#import "NSMutableArray+Extension.h"
#import <objc/runtime.h>
@implementation NSMutableArray (Extension)

+ (void)load {

Class arrayMClass = NSClassFromString(@"__NSArrayM");
//獲取系統(tǒng)的添加元素的方法
Method addObject = class_getInstanceMethod(arrayMClass, @selector(objectAtIndexedSubscript:));

//獲取我們自定義添加元素的方法
Method avoidCrash = class_getInstanceMethod(arrayMClass, @selector(avoidCrashobjectAtIndexedSubscript:));

method_exchangeImplementations(addObject, avoidCrash);


}

- (id)avoidCrashobjectAtIndexedSubscript:(NSUInteger)idx {

@try {
return [self avoidCrashobjectAtIndexedSubscript:idx];
}
@catch (NSException *exception) {
//你可以在這里進行相應(yīng)的操作處理
NSLog(@"這里數(shù)組越界");
NSLog(@"異常名稱:%@   異常原因:%@",exception.name, exception.reason);
}
@finally {

}
}
 

@end
NSException4.png

我們可以根據(jù)NSException的特性寫一些簡單的防止崩潰的框架。

NSError

每個程序都必須處理運行時發(fā)生的錯誤。例如,程序可能無法打開文件,或者可能無法解析XML文檔。通常這些錯誤需要程序通知用戶它們。 在程序中我們可以通過NSError把導(dǎo)致錯誤的原因回調(diào)給調(diào)用者

NSError對象里封裝了三條信息:

  • 1、Error domain:錯誤范圍,其類型為字符串
    錯誤發(fā)生的范圍,也就是產(chǎn)生錯誤的根源,通常用一個特有的全局變量來定義。比方說,“處理URL的子系統(tǒng)”在從URL中解析或者取得數(shù)據(jù)時如果出錯了,那么就會使用NSURLErrorDomain來表示錯誤范圍。

  • 2、Error code:錯誤碼,其類型為整數(shù)
    獨有的錯誤代碼,用以指明在某個范圍內(nèi)具體發(fā)生了何種錯誤。某個特定的范圍內(nèi)可能會發(fā)生一系列相關(guān)錯誤,這些錯誤情況通常采用enum來定義。例如當(dāng)http請求出錯時,可能會把http狀態(tài)碼設(shè)為錯誤碼。

  • 3、User info:用戶信息,其類型為字典
    有關(guān)此錯誤的額外信息,其中或許包含一段“本地化的描述”,獲取還含有導(dǎo)致該錯誤發(fā)生的另外一個錯誤,經(jīng)由此種信息,可將相關(guān)錯誤串成一條“錯誤鏈”。

NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:121 userInfo:@{NSLocalizedDescriptionKey:@"本地化的錯誤描述"}];
NSLog(@"error.userInfo:%@\nerror.code:%ld", error.userInfo,error.code);

Error官網(wǎng)

NSException官網(wǎng)

NSException:錯誤處理機制---調(diào)試中以及上架后的產(chǎn)品如何收集錯誤日志

iOS被開發(fā)者遺忘在角落的NSException-其實它很強大

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容