【问题标题】:Managing list of error codes for NSError in objective c管理目标 c 中 NSError 的错误代码列表
【发布时间】:2012-03-03 23:51:16
【问题描述】:

在 Cocoa 和 Objective C 中,最喜欢的管理错误的方法似乎是使用 NSError * 对象,但是要构造一个错误对象,我们需要调用以下方法

+ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict

我的问题是,在整个应用程序中管理错误域、错误代码定义和用户信息字典以使错误代码、域和用户信息字典始终保持一致的最佳实践是什么?

【问题讨论】:

    标签: objective-c cocoa nserror


    【解决方案1】:

    一种常见的方法是在头文件中定义一些适当的常量,然后在需要的地方包含该头文件。这是一个非常简单的方法,看起来像:

    const NSString * kMyAppErrorDomain = @"com.example.myapp";
    const NSInteger kMyAppSomeError = 2;
    
    // key into user info dictionary
    const NSString * kMyAppProblemKey = @"MyAppProblemKey";
    

    我还看到一些应用程序创建了用于创建这些的便捷方法,或者作为NSError 上的一个类别,或者作为一个单独的实用程序类或一组函数。继承NSError 也是完全合理的,例如自定义本地化描述。

    如果您还没有看过它,Apple 已经发布了 Error Handling Programming Guide,其中讨论了如何在 Cocoa 中使用它们。

    【讨论】:

      【解决方案2】:

      如果你有大量的错误构造,你的生活可以通过使用一个类来简单得多。我实际上为此使用 C++,因此可以删除程序不需要的调用(与 objc 不同),但您可以为此使用 C、ObjC 或 C++:

      MONErrorDomain.h

      // you won't normally need an instance here
      @interface MONErrorDomain : NSObject
      
      + (NSString *)domain; // << required override
      - (NSString *)domain; // << returns [[self class] domain]
      
      // example convenience methods:
      // uses [self domain]
      + (NSError *)errorWithErrorCode:(NSInteger)errorCode; // << user info would be nil
      + (NSError *)errorWithErrorCode:(NSInteger)errorCode userInfo:(NSDictionary *)userInfo;
      
      @end
      

      MONKoalaError.h

      @interface MONKoalaError : MONErrorDomain
      
      + (NSError *)outOfEucalyptus;
      
      @end
      
      extern NSString * const MONKoalaErrorDomain;
      
      typedef enum MONKoalaErrorCode {
        MONKoalaErrorCode_Undefined = 0,
        MONKoalaErrorCode_OutOfEucalyptus
      } MONKoalaErrorCode;
      

      MONKoalaError.m

      // apple recommends we use reverse domains
      NSString * const MONKoalaErrorDomain = @"com.mon.koala-library.MONKoalaErrorDomain";
      
      @implementation MONKoalaError
      
      + (NSString *)domain
      {
        return MONKoalaErrorDomain;
      }
      
      + (NSError *)outOfEucalyptus
      {
        NSDictionary * info = …;
        return [self errorWithErrorCode:MONKoalaErrorCode_OutOfEucalyptus userInfo:info];
      }
      
      @end
      

      然后,每个域的错误创建都集中在一个地方,客户端可以轻松选择错误,而无需实际手动构建它们:

      if (outError) {
        *outError = [MONKoalaError outOfEucalyptus];
      }
      

      错误处理采用以下形式:

      if ([e.domain isEqualToString:MONKoalaErrorDomain]) {
        switch (e.code) {
          case MONKoalaErrorCode_OutOfEucalyptus : {
            self.needsEucalyptus = true;
      …
      

      【讨论】:

      • 只是一个小评论:虽然程序退出代码不应混淆 NSError 错误代码,但我发现错误代码等于 0 是反直觉的。我更喜欢将 -1 用于未定义错误。
      • @Alerty 0 用于未定义,因为当程序员引入逻辑错误(例如消息nil 或在调试中使用默认初始化内存)时,它是一个更可预测的值。也就是说,如果确实是MONKoalaErrorCode的错误,则该错误永远不应该返回MONKoalaErrorCode_Undefined
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多