扩展NSError是否是一个好习惯

问题描述:

对不起,提出这个问题。我知道在java中我们正在扩展异常类的自定义异常。但是我在目标c中看不到任何场景。扩展NSError是否是一个好习惯

所以我的问题是扩展NSError并引入自定义错误是一个好习惯吗?如果是这样的话,我们应该扩展NSError类。我也检查过这个文件。但是我看不到NSError的重要提示。

+5

我没有看到需要,因为NSError提供了一个域属性,您可以将其设置为任何域特定的值。你想用“NSError”子类添加什么值? – *foe 2014-10-27 13:36:36

+1

我也这么想。但让我们说一些场景,例如暴露一些关于错误的更多信息。可能是一些特定领域的细节。 – uiroshan 2014-10-27 13:38:44

+4

再次,通过向'userInfo'字典中添加条目已被'NSError'覆盖。 – *foe 2014-10-27 13:39:41

我从来没有见过这样做,这是因为NSError已经非常多才多艺。它允许通过设置domaincode属性来定义错误类型,并允许在userInfo字典中附加任意附加信息。

所以,不,这不是好习惯。

+0

欲了解更多信息,请查看NSHipster的[NSError文章](http://nshipster.com/nserror/)。到目前为止,我见过的唯一一个地方有一个巨大的可能的NSErrors列表。 – 2015-09-04 13:32:21

+1

由于它是在Apple文档中编写的,因此可以继承子类。 – Ramis 2015-09-22 10:43:21

尽管我同意你不应该子类NSError,但在其上放上类别非常有用,我经常这样做。例如,假设系统经常发布来自某个JSON块的错误。我会找到像创建一个类可以很方便:

@interface NSError (MyErrors) 
// Construct an NSError from data in JSON. 
// Include full JSON response in the userInfo 
+ (NSError *)myErrorWithJSON:(JSON *)json; 

// Parse the text out of the user info 
- (NSString *)myErrorMessage; 

// The full JSON error block as a string 
- (NSString *)myErrorJSON; 

// BOOLs can be helpful sometimes, or you could return an enum for use in a switch. 
- (BOOL)myIsNetworkError; 
- (BOOL)myIsAuthError; 
@end 

我经常写小帮手构建NSError更简单地说,建设用户信息的方式我想,和拉数据背出用户信息的不来电需要了解其内部表示。我认为这是一种非常好的数据隐藏形式,并鼓励使用更多的描述性信息。

同样,即使是较小的项目,我也经常创建一个+myErrorWithCode:localizedDescription:类别方法。我知道我的域名,所以我通常不需要通过该域名,这使得在用户信息中设置NSLocalizedDescription密钥变得更容易。同样,这样可以更容易地创建更好的错误,并且可以更轻松地更改错误处理的实现细节。

扩展NSError并不是一个坏主意。 我也为NSError做了一个类别供我自己使用。我想与你分享。

(1)做一个strings文件来定义所有的错误代码:

/* Following are general error messgaes those we can show to user 
    regarding to Internet connection and request. You can add more 
    codes. */ 

"-1001" = "Connection time out"; 
"-1003" = "Cannot find Host"; 
"-1004" = "Cannot connect to Host"; 
"-1005" = "Server is temporarily down"; 
"-1009" = "The Internet connection appears to be offline"; 
"-1012" = "Authentication failed"; 
"2000" = "This is a custom error message"; // custom created error code 

/* Always describe unknow error with whatever you want in 
    except case (i.e. except error codes). If not mentioned 
    the following line, still you will get message "Unknown error" */ 
"Unknown error" = "Network error occured"; 

(2)请在NSError一个类别,因此我们说 “NSError + ERRORINFO”:

@interface NSError (ErrorInfo) 

-(NSString *)userDescription; 

@end 

(3)定义它:

#define ERROR_KEY(code)     [NSString stringWithFormat:@"%d",code] 
#define ERROR_LOCALIZED_DESCRIPTION(code) NSLocalizedStringFromTable(ERROR_KEY(code),@"Errors",nil) 

@implementation NSError (ErrorInfo) 

-(NSString *)userDescription 
{ 
    NSString *errorDescrption = NSLocalizedStringFromTable(ERROR_KEY(self.code),@"Errors",nil); 

    if (!errorDescrption || [errorDescrption isEqual:ERROR_KEY(self.code)]){ 
     return NSLocalizedStringFromTable(@"Unknown error",@"Errors",nil);; 
    } 

    else{ 
     return ERROR_LOCALIZED_DESCRIPTION(self.code); 
    } 

    return nil; 
} 

@end 

(4)利用它:

NSError *yourError; // This can be any NSError object you get 
yourError = [NSError errorWithDomain:@"yourDomain" code:2000 userInfo:details]; // Just for test 
NSLog(@"%@",[yourError userDescription]); 

在文档编写,这是确定的子类:

应用程序可以选择创建NSError的子类,例如, 通过重写 localizedDescription来提供更好的本地化错误字符串。

在我来说,我与OSStatus这是的Int32工作。 NSError构造器仅支持Int。所以我需要将它继承以支持OSSStatus