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

How to correctly handly NSError** pointers?

处理 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。这是通过传递 pointer/address 而不是对象 (...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

在方法之间传递错误并检查是否发生错误的正确方法是什么?

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

  1. 一个方法可以通过一个NSError **参数return一个NSError对象,这样的方法也应该有一个非voidreturn 类型并通过其 return 值指示成功或失败。因此,使用您的示例,如果 dataWithJSONObject:options:error: 遇到错误,dataWithJSONObject:options:error: 将 return nil 并且 可能 return 通过其第三个错误对象参数.

  2. 任何接受 NSError ** 错误参数的方法 returns 应该接受 NSError * 变量的地址 NULL。后一个值意味着用户不希望有一个错误对象 returned。这意味着接受 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