在ARC托管的代码中使用__attribute__

时间:2011-10-01 17:41:20

标签: objective-c cocoa automatic-ref-counting

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

但是,该指南似乎很少说明这些声明所持有的实际必要程度。在运行静态分析器和运行项目本身时,排除它们似乎没有任何区别。这些甚至有所作为吗?使用__attribute__((objc_method_family(new)))标记方法有什么好处吗?我在ARC上找到的文章都没有提到这些说明者;也许一位ARC大师可以说出这些用途是什么。

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

3 个答案:

答案 0 :(得分:5)

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

  

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

     

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

您通常不会执行这些操作,因此通常不会使用这些属性。没有属性,正常的行为--NARC规则,或者可能在ARC下我应该说CAN-是编译器实现和期望的。

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

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

答案 1 :(得分:3)

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

即,如果声明一个名为initWith...的方法,它会自动将其视为“init”系列方法,无需指定__attribute__((objc_method_family(init))),Clang会自动检测它;同样适用于new家庭等。

事实上,当Clang无法猜出这种情况时,你只需要使用__attribute__说明符,这在实践中很少发生(实际上我从来没有使用它),或者只有你不这样做尊重命名约定:


引用Clang Language Extensions Documentation

  

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

因此,只要您尊重命名约定(您应该经常这样做),您将无法做任何事情。

答案 2 :(得分:0)

你应该尽可能坚持命名约定。