【问题标题】:Objective-C Error Handling with Enum like in Swift像在 Swift 中一样使用枚举的 Objective-C 错误处理
【发布时间】:2018-09-05 06:12:49
【问题描述】:

我刚刚开始熟悉 Objective-C,因为我的主要语言是 Swift。而且我找不到使用 Objective-c 枚举处理错误情况的最佳方法,因为我可以使用 Swift 做同样的事情。

例如在 Swift 中,我可以使用方便的枚举来处理错误:

import Foundation

public enum ErrorCases: Error, LocalizedError {
    case invalidURL(String)
    case JSONStringConversionError(String)
    case JSONStringifyError(Any?)
    case hashArrayCastError(Any)

    public var localizedDescription: String {
        switch self {
        case .invalidURL(let url): return "Invalid URL: \(url)."
        case .JSONStringConversionError(let jsonString): return "Cannot convert string to JSON, string: \(jsonString)."
        case .JSONStringifyError(let data): return "Cannot stringify JSON dictionary with 'Any' data to a string, data: \(String(describing: data))."
        case .hashArrayCastError(let hashArray): return "Cannot cast JSON with '#' key to an arrray of 'Any' objects from massage, JSON: \(hashArray)."
        }
    }
}

现在我可以像这样使用那个枚举了:

if error != nil {
    self.onError(error: ErrorCases.invalidURL(self.mUrl))
}

您能否推荐一种更好的方法来实现相同的错误处理,但使用 Objective-C! 感谢您的帮助。

【问题讨论】:

    标签: objective-c swift error-handling enums


    【解决方案1】:

    在 objC 中,你不能真正做同样的事情,因为枚举不能有关联的值。 objC 中的错误处理主要是通过 NSError 对象来完成的。 在您的情况下,我建议创建一个枚举:

    typedef NS_ENUM(NSInteger, ErrorCaseType) {
        ErrorCaseTypeInvalidURL,
        ErrorCaseTypeJSONStringConversionError,
        ErrorCaseTypeJSONStringifyError,
        ErrorCaseTypeHashArrayCastError
    };
    

    然后在出错时,创建一个错误对象:

    error = [NSError errorWithDomain:@"com.myapp.mydomain" 
                                    code: ErrorCaseTypeInvalidURL
                                userInfo:@{NSLocalizedDescriptionKey : NSLocalizedString(@"Oops...", nil)}];
    

    当收到错误时,您可以访问 [error code] 值并根据您的枚举检查它或/并显示 [error localizedDescription] 文本。

    您可以在此处找到有关错误对象的更多信息: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/CreateCustomizeNSError/CreateCustomizeNSError.html#//apple_ref/doc/uid/TP40001806-CH204-BAJIIGCC

    【讨论】:

      【解决方案2】:

      我能想到的更好的解决方案是这样的:

      ErrorCase.h

      typedef NS_ENUM(NSInteger, ErrorCaseType) {
          ErrorCaseTypeInvalidURL,
          ErrorCaseTypeJSONStringConversionError,
          ErrorCaseTypeJSONStringifyError,
          ErrorCaseTypeHashArrayCastError
      };
      
      @interface ErrorCase : NSObject
      
      @property (readonly, assign) ErrorCaseType errorType;
      @property (readonly, assign) NSString *URL;
      @property (readonly, assign) NSString *jsonString;
      @property (readonly, assign) id data;
      @property (readonly, assign) id hashArray;
      
      + (instancetype) InvalidURL:(NSString *)URL;
      + (instancetype) JSONStringConversionError:(NSString *)jsonString;
      + (instancetype) JSONStringifyError:(id)data;
      + (instancetype) HashArrayCastError:(id)hashArray;
      
      @end
      

      ErrorCase.m

      @interface ErrorCase ()
      
      @property (readwrite, assign) ErrorCaseType errorType;
      @property (readwrite, assign) NSString *URL;
      @property (readwrite, assign) NSString *jsonString;
      @property (readwrite, assign) id data;
      @property (readwrite, assign) id hashArray;
      
      @end
      
      @implementation ErrorCase
      
      + (instancetype) InvalidURL:(NSString *)URL {
          ErrorCase *error = [[ErrorCase alloc] init];
          error.URL = URL;
          error.errorType = ErrorCaseTypeInvalidURL;
          return error;
      }
      
      + (instancetype) JSONStringConversionError:(NSString *)jsonString {
          ErrorCase *error = [[ErrorCase alloc] init];
          error.jsonString = jsonString;
          error.errorType = ErrorCaseTypeJSONStringConversionError;
          return error;
      }
      
      + (instancetype) JSONStringifyError:(id)data {
          ErrorCase *error = [[ErrorCase alloc] init];
          error.data = data;
          error.errorType = ErrorCaseTypeJSONStringifyError;
          return error;
      }
      
      + (instancetype) HashArrayCastError:(id)hashArray {
          ErrorCase *error = [[ErrorCase alloc] init];
          error.hashArray = hashArray;
          error.errorType = ErrorCaseTypeHashArrayCastError;
          return error;
      }
      
      @end
      

      你可以这样使用它

      ErrorCase *errorCase = [ErrorCase InvalidURL:@"https://example.com"];
      
      switch (errorCase.errorType) {
          case ErrorCaseTypeInvalidURL: NSLog(@"Invalid URL %@", errorCase.URL); break;
          case ErrorCaseTypeJSONStringConversionError: NSLog(@"Conversion Error %@", errorCase.jsonString); break;
          case ErrorCaseTypeJSONStringifyError: NSLog(@"Stringify Error %@", errorCase.data); break;
          case ErrorCaseTypeHashArrayCastError: NSLog(@"Cast Error %@", errorCase.hashArray); break;
      }
      

      【讨论】:

      • 在实现上可能看起来很丑,但界面并没有那么糟糕。
      • 永远不要对对象使用assign 属性,除非你真的,真的知道你在做什么!正如@clemens 所说,这些可能会导致悬空指针。字符串应该都是copyid应该是strongretain
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多