iOS中NSError的使用

??NSError 來對錯(cuò)誤信息進(jìn)行封裝,它主要由3部分內(nèi)容組成:

  • domain 錯(cuò)誤發(fā)生域
  • code 錯(cuò)誤碼
  • userInfo 詳細(xì)信息
    ??使用NSError對象,除了封裝多種錯(cuò)誤信息,還可以歸檔保存,以及繼承后實(shí)現(xiàn)自定義行為。

Error Domain:

??首先,error domain簡稱錯(cuò)誤域,是一個(gè)字符串。通過 domain 屬性,可以對 error 信息進(jìn)行細(xì)分,domain 可以指明 error 對象代表的錯(cuò)誤具體是發(fā)生在哪一層框架,除了指明層級的 domain,一個(gè)框架或某一模塊的類都可以提供自己相關(guān)錯(cuò)誤的 domain 用于分類,當(dāng)然也包括自己實(shí)現(xiàn)的框架和類。另外,domain 相當(dāng)于對下述代表具體錯(cuò)誤原因的 code 提供了命名空間,避免了 code 的重復(fù)。

??在OS X中將error分為不同的domain。譬如,對于Carbon框架的Error,歸于OSStatus domain(NSOSStatusErrorDomain),對于POSIX error,歸于NSPOSIXErrorDomain,而對于我們的iOS開發(fā),一般使用NSCocoaErrorDomain。NSError.h定義了四個(gè)domain,如下:

// Predefined domain for errors from most AppKit and Foundation APIs.
FOUNDATION_EXPORT NSErrorDomain const NSCocoaErrorDomain;

// Other predefined domains; value of "code" will correspond to preexisting values in these domains.
FOUNDATION_EXPORT NSErrorDomain const NSPOSIXErrorDomain;
FOUNDATION_EXPORT NSErrorDomain const NSOSStatusErrorDomain;
FOUNDATION_EXPORT NSErrorDomain const NSMachErrorDomain;

??除了上述的四個(gè)domain之外,不同的framework定義了自己的domain,比如常見的網(wǎng)絡(luò)請求URL定義了NSURLErrorDomain。
??用戶也可以為自己的framework或者app定義自己的domain,官方推薦的domain命名是:
com.company.framework_or_app.ErrorDomain,例如:com.baidu.baiduMap.errorDomain

code

??NSInteger類型的 code 說明了 domain 下錯(cuò)誤的具體原因。這個(gè)信息對于程序開發(fā)來說極為有用。比如訪問URL資源timeout錯(cuò)誤對應(yīng)的是NSURLErrorTimedOut(-1001)。
iOS開發(fā)中常用的error code所對應(yīng)的頭文件如下:

//Generic Foundation錯(cuò)誤代碼
#import <Foundation/FoundationErrors.h> 
#import <CoreData/CoreDataErrors.h>
#import <Foundation/NSURLError.h>

??例如NSURLErrorTimedOut錯(cuò)誤碼就是NSURLError.h庫中的NSURLErrorDomain枚舉code。

userInfo

// 預(yù)定義的userinfo鍵名
NSString *const NSUnderlyingErrorKey;                  //推薦的標(biāo)準(zhǔn)方式,通用鍵
NSString *const NSLocalizedDescriptionKey;             // 詳細(xì)描述鍵
NSString *const NSLocalizedFailureReasonErrorKey;      // 失敗原因鍵
NSString *const NSLocalizedRecoverySuggestionErrorKey; //恢復(fù)建議鍵
NSString *const NSLocalizedRecoveryOptionsErrorKey;    // 恢復(fù)選項(xiàng)鍵
//其他鍵
NSString *const NSRecoveryAttempterErrorKey;
NSString *const NSHelpAnchorErrorKey;
NSString *const NSStringEncodingErrorKey ;
NSString *const NSURLErrorKey;
NSString *const NSFilePathErrorKey;

??通過 error 對象的 userInfo 字典,可以包含一些其他的自定義信息。NSError類內(nèi)置了幾個(gè)關(guān)于本地化描述錯(cuò)誤的 key,除了根據(jù) key 從 userInfo 中取值外,NSError還提供了對應(yīng)的只讀屬性來直接讀取相關(guān)信息。當(dāng)創(chuàng)建 error 對象時(shí),應(yīng)該在 userInfo 內(nèi)也提供這幾項(xiàng)內(nèi)容。

  • description
    通過屬性localizedDescription獲取 key 為NSLocalizedDescriptionKey中的內(nèi)容,該項(xiàng)是錯(cuò)誤的描述內(nèi)容,可能包含 failure reason。

  • failure reason
    通過屬性localizedFailureReason獲取 key 為NSLocalizedFailureReasonErrorKey中的內(nèi)容,該項(xiàng)是錯(cuò)誤原因的解釋

  • recovery suggestion
    通過屬性localizedRecoverySuggestion獲取 key 為
    NSLocalizedRecoverySuggestionErrorKey中的內(nèi)容,該項(xiàng)描述了用戶如何操作以修復(fù)錯(cuò)誤

  • recovery options
    通過屬性localizedRecoveryOptions獲取 key 為
    NSLocalizedRecoveryOptionsErrorKey中的內(nèi)容,該項(xiàng)是一個(gè)字符串?dāng)?shù)組,內(nèi)容是提供給用戶操作的按鈕的標(biāo)題,與 recovery suggestion 配合使用,默認(rèn)的順序規(guī)則是,第一個(gè)字符串應(yīng)該用于最右邊的按鈕,以此類推。
    下圖展示了上述幾項(xiàng)屬性的關(guān)系

    userInfo關(guān)系

  • recoveryAttempter
    獲取 userInfo 中 key 為NSRecoveryAttempterErrorKey的值,該值是一個(gè)實(shí)現(xiàn)了NSErrorRecoveryAttempting協(xié)議的實(shí)例,與 recovery options 配合使用,可以讓系統(tǒng)根據(jù)用戶選擇點(diǎn)擊的按鈕,執(zhí)行相應(yīng)的修復(fù)方法,但只能在 Cocoa 框架中使用。

  • helpAnchor
    獲取 userInfo 中 key 為NSHelpAnchorErrorKey的值,用于 Cocoa 框架中,
    NSAlert類執(zhí)行方法+ alertWithError:時(shí),展示的錯(cuò)誤提示框中 help anchor button 的標(biāo)題。

NSError 對象的創(chuàng)建

//兩種初始化方法:其中,domain 不能為空 dict可以為空
- (instancetype)initWithDomain:(NSErrorDomain)domain code:(NSInteger)code userInfo:(nullable NSDictionary<NSErrorUserInfoKey, id> *)dict NS_DESIGNATED_INITIALIZER;
+ (instancetype)errorWithDomain:(NSErrorDomain)domain code:(NSInteger)code userInfo:(nullable NSDictionary<NSErrorUserInfoKey, id> *)dict;

下面寫了一個(gè)自定義的NSError的demo作為參考

NSError+Common.h


#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

//domain
FOUNDATION_EXPORT NSString *const NSCommonErrorDomain;
/**錯(cuò)誤狀態(tài)碼*/
typedef NS_ENUM(NSInteger,NSCommonErrorCode){
    NSCommonErrorCodeUnKnow = -1000,
    NSCommonErrorCodeSucc = -1001,
    NSCommonErrorCodefailed = -1002,
};

@interface NSError (Common)
+(NSError*)errorCode:(NSCommonErrorCode)code;
+(NSError*)errorCode:(NSCommonErrorCode)code userInfo:(nullable NSDictionary*)userInfo;
@end

NS_ASSUME_NONNULL_END

NSError+Common.m

#import "NSError+Common.h"

NSString *const NSCommonErrorDomain = @"NSCommonErrorDomain";
@implementation NSError (Common)

+(NSError*)errorCode:(NSCommonErrorCode)code{
    return [self errorCode:code userInfo:nil];
}

+(NSError*)errorCode:(NSCommonErrorCode)code userInfo:(nullable NSDictionary*)userInfo{
    if (userInfo) {
        return [NSError errorWithDomain:NSCommonErrorDomain code:code userInfo:userInfo];
    }else{
        return [NSError errorWithDomain:NSCommonErrorDomain code:code userInfo:
                @{
                  NSLocalizedDescriptionKey:@"返回的消息?",
                  NSLocalizedFailureReasonErrorKey:@"失敗原因",
                  NSLocalizedRecoverySuggestionErrorKey:@"意見:恢復(fù)初始化",
                  @"自定義":@"自定義的內(nèi)容",
                  }];
    }
}
@end

Demo下載

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

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

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