【问题标题】:Is it a good practice to extend NSError扩展 NSError 是一个好习惯吗
【发布时间】:2014-12-22 16:45:57
【问题描述】:

很抱歉提出这个问题。我知道在 java 中我们正在为自定义异常扩展 Exception 类。但我在目标 c 中没有看到任何情况。

所以我的问题是,扩展 NSError 并引入自定义错误是一种好习惯吗?如果是这样,我们应该扩展 NSError 类。我也为此检查了文档。但我看不到 NSError 的重要注释。

【问题讨论】:

  • 我认为没有必要,因为NSError 提供了一个域属性,您可以将其设置为任何特定于域的值。您想通过 NSError 子类添加什么价值?
  • 我也是这么想的。但是让我们说一些场景,比如暴露更多关于错误的信息。可能是一些特定领域的详细信息。
  • 同样,NSError 已经通过向 userInfo 字典添加条目来覆盖。
  • 我明白了。所以没有像扩展 NSError 这样的概念。谢谢!
  • 一般来说,Cocoa 在类组合和实例配置方面做得更多,而在 Java 中找到的“子类一切”设计模式则更少。

标签: ios objective-c nserror


【解决方案1】:

在文档中写到可以子类化:

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

就我而言,我正在使用 OSStatus,即 Int32。 NSError 构造函数仅支持 Int。所以我需要继承它来支持OSSStatus

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      虽然我同意您不应该继承 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 键变得更加容易。同样,这通过使错误更容易创建来鼓励更好的错误,并且更容易更改错误处理的实现细节。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 有关更多信息,请查看 NSHipster 的 NSError article。到目前为止,我见过的唯一一个在一个地方有大量可能的 NSError 列表的地方。
        • 子类化是可以的,因为它是写在 Apple 文档中的。
        猜你喜欢
        • 2020-02-06
        • 2011-09-04
        • 2014-03-09
        • 1970-01-01
        • 2017-06-14
        • 1970-01-01
        • 2016-01-03
        • 1970-01-01
        • 2021-05-07
        相关资源
        最近更新 更多