在IT技术中,扩展NSError是一种好的实践吗?

11
抱歉提出这个问题。我知道在Java中,我们为自定义异常扩展Exception类。但是我在Objective C中没有看到任何这样的情况。
因此我的问题是,扩展NSError并引入自定义错误是否是一个好的实践?如果是的话,我们应该什么时候扩展NSError类?我也检查了相关文档,但我没有看到关于NSError的覆盖说明。

5
我认为不需要创建一个NSError子类,因为NSError已经提供了一个可以设置为任何特定值的“domain”属性。你考虑添加什么样的值? - trojanfoe
2
我也是这么想的。但是假设我们需要暴露有关错误的更多信息,例如一些特定于领域的细节呢? - uiroshan
4
е·Із»ЏйЂљиү‡еђ‘userInfoе­—е…ёж·»еЉ жқҰз›®пәЊз”±NSErrorжЏђдң›дғ†з›ёе…ізљ„覆盖。 - trojanfoe
我明白了,所以没有像扩展NSError这样的概念。谢谢! - uiroshan
2
一般来说,Cocoa 在类组合和实例配置方面做得更多,而不是像 Java 中那样“子类化一切”的设计模式。 - rickster
4个回答

15

我同意不应该对 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,将userinfo构建成我想要的形式,并从userinfo中提取数据,而不需要调用者知道它的内部表示。我发现这是一种非常好的数据隐藏形式,有助于使用更具描述性的消息。
同样,即使对于较小的项目,我通常也会创建一个+myErrorWithCode:localizedDescription:类别方法。我知道我的领域,所以我通常不需要传递该值,这使得在userinfo中设置NSLocalizedDescription键变得非常容易。同样,这鼓励了更好的错误处理,通过使其更易于创建,并使更改错误处理的实现细节变得更加容易。

9

我从未见过这样的做法,因为NSError已经非常灵活。它允许通过设置domaincode属性来定义错误类型,并允许在userInfo字典中附加任意其他信息。

所以,不,这不是一个好的做法。


有关更多信息,请查看NSHipster的NSError文章。到目前为止,这是我见过唯一一个将可能的NSErrors列出的巨大清单的地方。 - Miha Hribar
6
在苹果的文档中,按照现有的写法进行子类化是可以的。 - Ramis

7
在文档中写道可以进行子类化:
应用程序可以选择创建NSError的子类,例如通过覆盖localizedDescription提供更好的本地化错误字符串。
在我的情况下,我正在使用Int32的OSStatus。NSError构造函数仅支持Int。因此,我需要对其进行子类化以支持OSSStatus。

0

扩展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]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接