CF_RETURNS_RETAINED或CF_RETURNS_NOT_RETAINED:何时使用?

时间:2014-06-29 17:01:02

标签: objective-c automatic-ref-counting swift core-foundation

我不确定是否为我的自定义函数使用CF_RETURNS_RETAINED或CF_RETURNS_NOT_RETAINED返回CFDataProviderRef

根据the documentation at the location where the macros are defined,两者都应该仅在特殊情况下使用,并且正确的修复应该是修复我的命名约定。 然而,swift / objective-c文档suggests using它们用于注释返回CoreFoundation指针的任何函数,而没有真正解释何时使用哪个 - 如果我不注释它们我需要手动指定每个行为时间快速的代码。

我可以找到的进一步文档解释了如何使用+1值的AES值和0的另一个值,但是我担心这对我的理解并不太有帮助。

我的问题:

  1. 我应该完全使用它们,还是按Base.h建议改进我的命名?
  2. 那里使用的确切命名约定是什么?
  3. 如果我希望退回对象使用的内存一旦超出调用者的范围就可以自由使用,我可以正确使用一个,而另一个如果我不这样做希望这种情况发生(因为我在其他地方使用指针,或者自己清理)?
  4. 我的所有功能都是返回CFDataProviderRef,我是通过致电CGDataProviderCreateSequential来获得的。我想这意味着我希望行为为CGDataProviderCreateSequential(对吗?)。如何查找该函数是否使用CF_RETURNS_RETAINED或CF_RETURNS_NOT_RETAINED(CGDataProvider.h文件中没有)?

1 个答案:

答案 0 :(得分:10)

这都是关于所有权的。命名约定是Core Foundation的命名约定,其描述为here。创建规则表示使用"创建"和"复制"在他们的名字中,让调用者拥有返回对象的所有权(尽管不一定是唯一所有权)。这意味着调用者有责任使用CFRelease()最终释放返回的对象。 Get Rule表示除了创建或复制函数之外的函数不会给对象的调用者所有权,因此调用者不得在其上调用CFRelease()(除了平衡对CFRetain()的任何显式调用之外,疗程)。

如果一个函数在语义上是一个创建或复制函数,它将所有权返回给调用者,但它的名称并没有表明,你应该用CF_RETURNS_RETAINED来表示。同样,如果函数的名称包含" Create"或"复制"但它没有与创建规则匹配的语义,您应该使用CF_RETURNS_NOT_RETAINED来表示。 (尽量避免这种情况。)

由于您的代码正在调用CGDataProviderCreateSequential(),因为它有"创建"在名称中,您的代码负责释放返回的CGDataProvider对象。如果您在功能中将其释放,则您的呼叫者无法访问它。您想要将对象返回给调用者。您还希望将释放对象的责任传递给调用者,因为您不知道调用者何时完成它。因此,您应该使用"创建"来命名您的功能。在其名称中向呼叫者和自动系统指示调用者负责释放对象。或者,您可以使用CF_RETURNS_RETAINED注释您的函数来表示,但遵循命名约定更好。

Swift可能只尊重系统头的命名约定。我不知道。在这种情况下,即使您的功能具有"创建",您也必须使用CF_RETURNS_RETAINED进行注释。在它的名字。注释名称已经遵循约定的函数没有任何害处。这是多余的,但无害。