2014-10-27 3 views
7

Извините, что задал этот вопрос. Я знаю, что в java мы расширяем класс исключения для пользовательских исключений. Но я не вижу никаких сценариев для этого в объективе c.Разве это хорошая практика для расширения NSError

Итак, мой вопрос: Является ли хорошей практикой распространять NSError и вводить пользовательские ошибки? Если это так, когда мы должны расширить класс NSError. Я тоже проверил документацию. Но я не вижу замечательных заметок для NSError.

+5

Я не вижу необходимости, поскольку «NSError» предоставляет свойство домена, которое вы можете установить для любого значения для домена. Какую ценность вы думаете о добавлении с подклассом «NSError»? – trojanfoe

+1

Я тоже думал о том же. Но скажем, сценарии, как разоблачение некоторой информации об ошибке. Могут быть некоторые данные о конкретном домене. – uiroshan

+4

Опять же, уже покрытый 'NSError', добавляя записи в словарь' userInfo'. – trojanfoe

ответ

6

Я никогда не видел этого, и это потому, что NSError уже очень универсален. Это позволяет определить тип ошибки, установив свойства domain и code и позволяет произвольно добавлять дополнительную информацию в словарь userInfo.

Итак, нет, это не очень хорошая практика.

+0

Для получения дополнительной информации [NSError article] (http://nshipster.com/nserror/) от NSHipster. Пока единственное место, которое я видел, имеет огромный список возможных NSErrors в одном месте. –

+1

Это нормально для подкласса, поскольку оно написано в документации Apple. – Ramis

13

Хотя я согласен с тем, что вы не должны подкласса NSError, очень полезно размещать на нем категории, и я делаю это регулярно. Например, скажем, ваша система часто отправляет ошибки, которые поступают из некоторого блока JSON. Я нахожу это очень удобно для создания категории, как:

@interface NSError (MyErrors) 
// Construct an NSError from data in JSON. 
// Include full JSON response in the userInfo 
+ (NSError *)myErrorWithJSON:(JSON *)json; 

// Parse the text out of the user info 
- (NSString *)myErrorMessage; 

// The full JSON error block as a string 
- (NSString *)myErrorJSON; 

// BOOLs can be helpful sometimes, or you could return an enum for use in a switch. 
- (BOOL)myIsNetworkError; 
- (BOOL)myIsAuthError; 
@end 

Я часто пишу маленькие помощники, чтобы построить более NSError просто, построит UserInfo так, как я хочу, и тянуть данные обратно из UserInfo без звонящих необходимо знать его внутреннее представление. Я считаю, что это очень хорошая форма скрытия данных и поощряет использование более описательных сообщений.

Аналогичным образом, даже для небольших проектов, я часто создаю метод категории +myErrorWithCode:localizedDescription:. Я знаю свой домен, поэтому мне обычно не нужно его пропускать, и это упрощает установку ключа NSLocalizedDescription в информации о пользователе. Опять же, это способствует улучшению ошибок, упрощая их создание и упрощает изменение деталей реализации вашей обработки ошибок.

0

Неплохое предложение продлить NSError. Я также сделал категорию на NSError для моего собственного использования. Я хотел бы поделиться им с вами.

(1) Сделать strings файл, чтобы определить все коды ошибок:

/* Following are general error messgaes those we can show to user 
    regarding to Internet connection and request. You can add more 
    codes. */ 

"-1001" = "Connection time out"; 
"-1003" = "Cannot find Host"; 
"-1004" = "Cannot connect to Host"; 
"-1005" = "Server is temporarily down"; 
"-1009" = "The Internet connection appears to be offline"; 
"-1012" = "Authentication failed"; 
"2000" = "This is a custom error message"; // custom created error code 

/* Always describe unknow error with whatever you want in 
    except case (i.e. except error codes). If not mentioned 
    the following line, still you will get message "Unknown error" */ 
"Unknown error" = "Network error occured"; 

(2) Сделайте категорию на NSError, скажем "NSError + ErrorInfo":

@interface NSError (ErrorInfo) 

-(NSString *)userDescription; 

@end 

(3) Определить его:

#define ERROR_KEY(code)     [NSString stringWithFormat:@"%d",code] 
#define ERROR_LOCALIZED_DESCRIPTION(code) NSLocalizedStringFromTable(ERROR_KEY(code),@"Errors",nil) 

@implementation NSError (ErrorInfo) 

-(NSString *)userDescription 
{ 
    NSString *errorDescrption = NSLocalizedStringFromTable(ERROR_KEY(self.code),@"Errors",nil); 

    if (!errorDescrption || [errorDescrption isEqual:ERROR_KEY(self.code)]){ 
     return NSLocalizedStringFromTable(@"Unknown error",@"Errors",nil);; 
    } 

    else{ 
     return ERROR_LOCALIZED_DESCRIPTION(self.code); 
    } 

    return nil; 
} 

@end 

(4) использовать его:

NSError *yourError; // This can be any NSError object you get 
yourError = [NSError errorWithDomain:@"yourDomain" code:2000 userInfo:details]; // Just for test 
NSLog(@"%@",[yourError userDescription]); 
3

В документации написано, что это нормально подкласса:

Приложения могут выбрать для создания подклассов NSError, например, , , чтобы обеспечить лучшие локализованные строки ошибок, переопределяя localizedDescription.

В моем случае я работаю с OSStatus, который Int32. Конструктор NSError поддерживает только Int. Поэтому мне нужно подклассировать его для поддержки OSSStatus.

Смежные вопросы