在 Cocoa 和 Objective C 中,最喜欢的管理错误的方法似乎是使用一个NSError *
对象,但是要构造一个错误对象,我们需要调用以下方法
+ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict
我的问题是,在整个应用程序中管理错误域、错误代码定义和用户信息字典以使错误代码、域和用户信息字典始终保持一致的最佳实践是什么?
在 Cocoa 和 Objective C 中,最喜欢的管理错误的方法似乎是使用一个NSError *
对象,但是要构造一个错误对象,我们需要调用以下方法
+ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict
我的问题是,在整个应用程序中管理错误域、错误代码定义和用户信息字典以使错误代码、域和用户信息字典始终保持一致的最佳实践是什么?
如果你有大量的错误构造,你的生活可以通过使用一个类来简单得多。我实际上为此使用 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;
…
一种常见的方法是在头文件中定义一些适当的常量,然后在需要的地方包含该头文件。这是一个非常简单的方法,看起来像:
const NSString * kMyAppErrorDomain = @"com.example.myapp";
const NSInteger kMyAppSomeError = 2;
// key into user info dictionary
const NSString * kMyAppProblemKey = @"MyAppProblemKey";
我还看到一些应用程序创建了用于创建这些的便捷方法,或者作为一个类别,NSError
或者作为一个单独的实用程序类或一组函数。子类化也是完全合理的NSError
,例如自定义本地化描述。
如果您还没有看过它,Apple 已经发布了错误处理编程指南,其中讨论了如何在 Cocoa 中使用这些。