Как правильно обрабатывать указатели NSError **? - PullRequest
0 голосов
/ 30 октября 2018

Как правильно обращаться с указателями NSError **?

- (BOOL)handleData:(NSDictionary *)data error:(NSError **)error {
    // pass the error pointer to NSJSONSerialization
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:options error:error];

    // Check if NSJSONSerialization had errors
    if (error)  // <-- sometimes this works, sometimes it crashes...
       return false;

    ...

    return true;
}

- (void)someMethod {
    NSError *error = nil;
    BOOL result = [self handleData:dataDict error:&error]; 

    if (error) {
       // an error occurred
    } else {

    }
}

В этом примере someMethod передает ссылку NSError на handleData:error. Это делается путем передачи указателя / адреса вместо объекта (...error:&error)

Затем метод handleData:error передает этот указатель на dataWithJSONObject:options:error (теперь без &). Теперь я хотел бы проверить, произошла ли ошибка, но как правильно это сделать?

if (error)...   
// This works if error == nil. However this is not always the case. 
// Sometimes error is some address (e.g. 0x600001711f70) and *error == nil
// from the start of the method (passing error to NSJSONSerialization has no 
// influence on this

if (*error)...
// This works in cases where error itself is not nil, but it crashes if
// error == nil

Почему error == nil в некоторых случаях и error != nil, но *error == nil в других?

Как правильно передать ошибку между методами и проверить, произошла ли ошибка?

1 Ответ

0 голосов
/ 30 октября 2018

Место, где можно найти ответы: Введение в руководство по программированию обработки ошибок для какао . Соглашения:

  1. Метод может возвращать объект NSError через параметр NSError **, такой метод также должен иметь тип возврата не void и указывать успех или неудачу через свое возвращаемое значение. Поэтому, используя ваш пример, dataWithJSONObject:options:error: вернет nil, если обнаружит ошибку, и может вернуть объект ошибки через третий параметр.

  2. Любой метод, принимающий параметр NSError ** для возврата ошибок, должен принимать либо адрес NSError * переменной , либо NULL. Последнее значение означает, что пользователь не хочет возвращать объект ошибки. Это означает, что метод, принимающий NSError ** параметр , должен проверить, что значение параметра не равно NULL, прежде чем пытаться назначить объект ошибки через него.

Таким образом, ваш метод handleData:error: должен быть готов принять NULL и должен проверить его. Следовательно, ваш код должен содержать что-то похожее на:

// Check if NSJSONSerialization had errors
if (jsonData == nil)
{
   // Error occurred, did it return an error object?
   if (error != NULL && *error != nil)
   {
       // we have an error object
   }
   else
   {
      // we have an error but no error object describing it
   }
}
else
{
   // no JSON error
}

НТН

...