代码之家  ›  专栏  ›  技术社区  ›  Pavel Bogart

Swift中类枚举的Objective-C错误处理

  •  2
  • Pavel Bogart  · 技术社区  · 8 年前

    我刚刚熟悉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! 谢谢你的帮助。

    2 回复  |  直到 8 年前
        1
  •  2
  •   Florian Burel    8 年前

    在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
  •  0
  •   Gonzo    8 年前

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

    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;
    }