2

当 ARC 来到 Objective-C 时,我尽力通读了 Clang 项目网站上发布的Objective-C 自动引用计数 (ARC)指南,以便更好地了解它的内容。我在那里发现(并且没有其他地方)提到使用__attribute__声明向 ARC 表示某些代码是否自动释放其返回值,例如 ( __attribute__((ns_returns_autoreleased))),或者它是否“使用”参数 (__attribute((ns_consumed))等​​等。

然而,该指南似乎对这些声明所具有的实际必要性几乎没有给出任何字眼。排除它们似乎没有什么区别,无论是在运行静态分析器还是在运行项目本身时。这些甚至有影响吗?用 标记方法有什么好处__attribute__((objc_method_family(new)))吗?我在 ARC 上找到的任何文章都没有提到这些说明符。也许 ARC 大师可以说明它们的用途。

(就个人而言,我包括所有相关的说明符以防万一,但发现它们使代码变得混乱和混乱。)

4

3 回答 3

5

这些属性明确用于异常情况,例如:

可保留对象指针类型的函数或方法参数可以标记为已使用,表示被调用者期望获得 +1 保留计数的所有权。

返回可保留对象指针类型的函数或方法可以标记为返回保留值,表示调用者期望获得 +1 保留计数的所有权。

你通常不会做这些事情,所以你通常不会使用这些属性。在没有属性的情况下,正常行为——NARC 规则,或者可能在 ARC 下我应该说 CAN——是编译器实现和期望的。

使用这些属性有两个原因:

  • 为了违反CAN规则;也就是说,有一个没有这样命名的方法返回一个引用,或者一个没有这样命名的方法。该属性记录了方法原型中的违规行为,如果实现使用 ARC,甚至可能需要实现它。
  • 使用 Core Foundation 类型,包括 Core Graphics 类型。这些不是 ARCed,因此您需要使用桥接属性来帮助与“可保留对象指针”类型之间的转换。
于 2011-10-01T18:12:36.737 回答
3

在大多数情况下,这不是必需的,因为 LLVM 和 Clang 知道 ObjC 命名约定。因此,如果您遵循 Cocoa 的标准命名约定,LLVM 会自动假定要遵循相应的系列/返回内存策略。

即,如果你声明了一个名为initWith...it 的方法,会自动将其视为“init”方法族,无需指定__attribute__((objc_method_family(init))),Clang 会自动检测;对new家庭等也是如此。

事实上,你只需要__attribute__在 Clang 猜不到这种情况时才需要使用说明符,这在实践中很少发生(实际上我从来没有使用过),或者只有在你不遵守命名约定的情况下:


引用Clang 语言扩展文档

Objective-C 中的许多方法具有由它们的选择器确定的常规含义。出于静态分析的目的,有时即使没有正确的选择器,也可以将方法标记为具有特定的传统含义,或者不具有其选择器所暗示的传统含义。对于这些用例,我们提供了一个属性来专门描述一个方法所属的方法族。

因此,只要您尊重命名约定(您应该始终这样做),您将无事可做。

于 2011-10-01T18:11:49.523 回答
0

您绝对应该尽可能地坚持命名约定。

于 2011-10-14T19:12:05.810 回答