如何正确处理NSError **指针?

时间:2018-10-30 10:41:08

标签: objective-c pointers nserror

处理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 {

    }
}

在此示例中,someMethodNSError引用传递给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 :(得分:2)

找到答案的地方是Introduction to Error Handling Programming Guide For Cocoa。约定为:

  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
}

HTH