有人能给我解释一下在下面的示例代码块中使用__autoreleasing的目的吗?

- (void)execute:(NSError * __autoreleasing *)error {
    // do stuff, possibly assigning error if something went wrong
}

我删除了__autoreleasing,但一切似乎仍能正常编译/运行.我开始使用obj-c post ARC,所以我从来没有真正学会/理解所有那些双下划线的东西.我读过ARC transition guide,但我不完全理解他们的N错误示例.

推荐答案

考虑ARC如何使用variables——每个引用变量都有一个模式(隐式或显式):strong, weak,等等.这个模式让我们知道如何处理读写变量;e、 g.对于strong变量,读取不需要额外操作,而写入则需要先释放变量中的现有引用,然后再替换为新引用.ARC需要知道任何变量的模式才能起作用.

现在考虑通过reference的变量,例如,对于execute,你将有一个电话:

NSError *myError = nil;
...
[someObject execute:&myError]; // pass the variable itself by reference, not the variables value

execute人的主体将包含一项任务,内容大致如下:

- (void)execute:(NSError * __autoreleasing *)error
{
   ...
   if (error != NULL)
      *error = [NSError ...]; // assign indirectly via the reference to a variable
   ...
}

现在,对于间接赋值,ARC需要知道被引用变量的模式,以便知道如何读写.这就是声明中的__autoreleasing,它告诉ARC它已被传递到模式为autoreleasing的变量的引用,并告诉ARC如何读取和写入变量的内容.go 掉__autoreleasing,默认模式将被假定,在这种情况下,我建议明确无疑是好的.

autoreleasing模式意味着变量包含一个不属于自己的引用,如果需要,读取应该是retain,写入可以只是写入.它主要用于通过引用传递的变量.

您可能会注意到,在上面的示例中,变量myError具有模式strong(隐式),但它是以autoreleasing的形式通过引用传递的——编译器通过引入一个临时自动释放变量来自动处理这个问题,将without复制到其中,将当前引用保留在myError中,并将临时引用作为参数传递给execute:.调用返回后,编译器执行从临时到myError的正常赋值,这会导致释放所有旧引用,并保留返回的引用.

更多详情请参见Apple's Transitioning to ARC Release Notes

Followup to Comments

问:__autoreleasing是隐式设置的吗?

答:Apple's文档并不具体,但Clang documentation表示间接参数是隐式的.如上所述,我建议明确,清晰是一件好事™.

问:位置重要吗?

A:是的,也不是...这是一个C声明,是问答题的内容("下面声明了什么……").限定符应该在两个星号之间,因为它是pointer to a (variable of type) autoreleasing pointer to an object,但苹果表示编译器"原谅"了,但没有具体说明它原谅了什么.注意安全,把它放在正确的地方.

问:在做间接作业(job)之前,你不应该测试error分为NULL分吗?

答:你当然应该,在你做间接推理之前的某个地方.显示的代码只是一个大纲,这样的细节在...年代被省略和覆盖.然而,由于这些年来它被提出了几次,可能我省略了太多,所以添加了一个合适的if.

Objective-c相关问答推荐

错误无法使 UICollectionElementKindCell 类型的视图出列

Xcode 是否支持区域?

当前时间是 HH:MM:SS am/pm 格式吗?

如何使用 NSString drawInRect 使文本居中?

如何知道 NSAssert 在发布版本中是否被禁用?

如何在 iPhone 上默认显示数字键盘?

我们可以在 UIPageViewController 中自定义页面指示器吗?

用于 iOS 开发的 LLVM 与 GCC

使用情节提要的条件转场

未知类型名称类;您指的是 'Class' 吗?

当表格重新出现时,UITableView 不会自动取消 Select 选定的行

UIKeyboardBoundsUserInfoKey 已弃用,改用什么?

反转 NSString 文本

使用 NSLog 打印 NSData

Modal segue,导航栏消失

AVAssetImageGenerator 提供旋转的图像

UICollectionView 仅在用户双击时调用 didSelectItemAtIndexPath,当用户单击时不会调用

NS_ASSUME_NONNULL_BEGIN 宏

如何调整 UITableView 中原型单元格的左边距?

iOS 上的电话号码格式