2012-02-12 21 views
5

Trong Cocoa và Mục tiêu C phương pháp ưa thích để quản lý lỗi dường như được sử dụng một đối tượng NSError *, để xây dựng một đối tượng lỗi tuy nhiên, chúng ta cần phải gọi phương thức sau đâydanh sách các mã lỗi Quản lý cho NSError trong khách quan c

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

Câu hỏi của tôi là, một số phương pháp hay nhất để quản lý miền lỗi, định nghĩa mã lỗi và từ điển thông tin người dùng trên toàn bộ ứng dụng để mã lỗi, tên miền và thông tin người dùng luôn luôn nhất quán là gì?

Trả lời

10

Nếu bạn có một số tiền khổng lồ của việc xây dựng lỗi, cuộc sống của bạn có thể đơn giản hơn nhiều bằng cách sử dụng một lớp học. Tôi thực sự sử dụng C++ cho điều này nên các cuộc gọi một chương trình không cần có thể được gỡ bỏ (không giống như objc), nhưng bạn có thể sử dụng C, ObjC, hoặc C++ cho việc này:

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 

Sau đó, việc tạo ra lỗi là tất cả ở một nơi cho từng lĩnh vực, và các khách hàng có thể dễ dàng nhận lỗi của họ mà không thực sự xây dựng chúng bằng tay:

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

và xử lý lỗi có dạng:

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

Chỉ cần một bình luận nhỏ: trong khi một mã lỗi NSError không nên bị nhầm lẫn bởi mã thoát chương trình, tôi thấy nó truy cập trực quan để có một mã lỗi bằng 0. Tôi thích có -1 cho một lỗi không xác định. – Alerty

+0

@Alerty '0' được sử dụng cho không xác định vì đó là giá trị dễ đoán trước hơn khi lập trình viên đưa ra lỗi logic (ví dụ: thư' nil' hoặc sử dụng bộ nhớ khởi tạo mặc định trong gỡ lỗi). đó là để nói, lỗi sẽ không bao giờ trả về 'MONKoalaErrorCode_Undefined' nếu nó thực sự là một lỗi của' MONKoalaErrorCode'. – justin

3

Một cách phổ biến là xác định một số hằng số thích hợp trong tệp tiêu đề và sau đó bao gồm tệp tiêu đề đó bất cứ khi nào cần. Đó là một cách tiếp cận khá đơn giản, và trông giống như:

const NSString * kMyAppErrorDomain = @"com.example.myapp"; 
const NSInteger kMyAppSomeError = 2; 

// key into user info dictionary 
const NSString * kMyAppProblemKey = @"MyAppProblemKey"; 

Tôi cũng đã nhìn thấy một số ứng dụng mà tạo ra phương pháp thuận tiện cho việc tạo ra này, hoặc như một phạm trù trên NSError hoặc như là một lớp tiện ích riêng biệt hoặc thiết lập các chức năng. Nó cũng hoàn toàn hợp lý để phân lớp NSError, ví dụ để tùy chỉnh mô tả được bản địa hóa.

Nếu bạn chưa thấy nó, Apple đã phát hành Error Handling Programming Guide thảo luận về cách thức chúng nên được sử dụng trong Cocoa.

+0

ah, hướng dẫn xử lý lỗi thực sự hữu ích. cảm ơn! – Tony

Các vấn đề liên quan