Objective-c передает параметр ошибки в метод inside

Это общий шаблон для добавления параметра вывода ошибок при написании методов Objective-c.
Насколько я знаю, это то, как вы создаете метод, который возвращает ошибку, если что-то не так:

- (void)doSomethingWithObj:(id)obj error:(NSError *__autoreleasing *)error {
    BOOL success = NO;

    // do somthing...

    if (!success) {
        *error = [NSError errorWithDomain:@"the.domain" code:0 userInfo:nil];
    }
}  

Теперь бывают случаи, когда вы просто хотите, чтобы этот параметр ошибки отражал ошибку, возникшую в каком-либо другом методе, который вы используете внутри своего метода, скажем:

- (void)fetchObjectInContext:(NSManagedObjectContext *)context error:(NSError *__autoreleasing *)error {
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SomeObject"];

    NSArray *results = [context executeFetchRequest:request error:nil];
}  

Итак, я подумал, что я просто передам параметр error внутреннему методу, вот так:

- (void)fetchObjectInContext:(NSManagedObjectContext *)context error:(NSError *__autoreleasing *)error {
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SomeObject"];

    NSArray *results = [context executeFetchRequest:request error:error];
    if (error) {
        NSLog(@"error %@", error);
    }
}  

Но у этого подхода есть две проблемы:
1. if (error) чек возвращается YES даже если нет ошибки.
2. строка журнала генерирует это предупреждение: Format specifies type 'id' but the argument has type 'NSError *__autoreleasing *'

Так что я здесь не так делаю?

2 ответа

Решение

Вы передаете адрес ошибки не фактическая ошибка это означает &errorТак что вам нужно разыменовать указатель ошибки.NSError *__autoreleasing * вы принимаете параметр в качестве адреса error. Обычно мы делаем это, потому что objective c может возвращать только одно значение. Но нужно знать об ошибке, откуда мы вызываем метод, поэтому передача его в качестве адреса ошибки приведет к изменению на ошибку, если в ней возникает ошибка calle function, Так что, если какая-либо ошибка появляется в строке ниже

NSArray *results = [context executeFetchRequest:request error:error];

чем это автоматически известно calle function т.е. doSomethingWithObj

if (*error) {
    NSLog(@"error %@", (*error).description);
 }

использование

NSLog(@"error %@", (*error).description);

вместо

NSLog(@"error %@", (error).description);

Вы должны пройти и ошибка

Есть пара вещей не так. Во-первых NSError Объект не должен использоваться для проверки на ошибки, вместо этого используйте возвращаемое значение метода. Поэтому ваш первый пример метода должен вернуть BOOL указать на успех:

- (BOOL)doSomethingWithObj:(id)obj error:(NSError *__autoreleasing *)error {
    BOOL success = NO;

    // do somthing...

    if (!success) {
        if (error) {    // Check it's been passed, and if so create the error object.
            *error = [NSError errorWithDomain:@"the.domain" code:0 userInfo:nil];
        }
    }

    return success;
}  

И проверить на results являющийся nilне error будучи неnil:

- (void)fetchObjectInContext:(NSManagedObjectContext *)context error:(NSError *__autoreleasing *)error {
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SomeObject"];

    NSArray *results = [context executeFetchRequest:request error:error];
    if (!results) {
        if (error && *error)
            NSLog(@"error %@", [(*error) localizedDescription]); // Here is your 2. I think.
        else
            NSLog(@"Unknown error");
    }
}  

Во-вторых error параметр обычно является необязательным (как видно из кода, где вы передаете nil, который должен быть NULL на самом деле). Поэтому вам нужно проверить, был ли он передан перед разыменованием (см. Код выше).

Однако, чтобы ответить на ваш общий вопрос, да, это хорошо, чтобы передать error Параметр наряду с подчиненными вызовами методов и обычно используется.

Я понятия не имею о вашем 2. пока вы не обновите свой код... в ожидании. Я думаю, что ваша проблема 2. потому что вам нужно использовать [error localizedDescription] с NSLog(),

Другие вопросы по тегам