以下iOS代码是否安全?(__autoreleasing语义)

QED*_*QED 2 autorelease ios automatic-ref-counting

-(NSData *)jsonRepresentation:(NSError **error)error {
   NSDictionary *dict = [self getDictRepresentation];
   return [NSJSONSerialization dataWithJSONObject:dict options:nil error:error];
}

// Some other place...

NSError *__autoreleasing error = nil;
NSData *json = [obj jsonRepresentation:&error];
Run Code Online (Sandbox Code Playgroud)

自动释放语义是否安全地将error堆栈传送到我的第二个代码块?

Lil*_*ard 5

根据clang ARC规范,NSError **隐式假设形式的方法参数(或者更确切地说,指向任何obj-c对象的指针)NSError * __autoreleasing *.这意味着该错误将在该方法中自动释放.

至于呼叫站点,如果你用__autoreleasing变量调用它,就像你拥有的那样,那么一切都很好.事实上,我推荐这种模式.但是,如果用__strong变量调用它,它仍然可以工作.在这种情况下,编译器将生成一个未命名的__autoreleasing临时,将该地址传递给该方法,然后在返回时,它将临时分配给__strong.所以,如果你有

NSError *foo;
[bar callMethodWithError:&foo];
Run Code Online (Sandbox Code Playgroud)

编译器将对此进行相同的处理

NSError *foo;
NSError * __autoreleasing tmp = foo;
[bar callMethodWithError:&tmp];
foo = tmp;
Run Code Online (Sandbox Code Playgroud)

实际上,如果标记了外部参数,它实际上稍微复杂一些out,但这通常是它的工作原理.