【问题标题】:Memory management of a CFErrorRef returned by ABRecordSetValueABRecordSetValue 返回的 CFErrorRef 的内存管理
【发布时间】:2011-12-25 01:32:08
【问题描述】:

考虑一些涉及错误处理的典型 CF 代码,这样说:

ABRecordRef aRecord = ABPersonCreate();
CFErrorRef anError = NULL;
ABRecordSetValue(aRecord, kABPersonFirstNameProperty, CFSTR("Joe"), &anError);

在这段代码之后我如何处理anError?我是否必须保留它,以确保它不会消失,然后再释放它?还是我已经是所有者,只需要稍后发布?

【问题讨论】:

  • 请注意,此示例中的anError 在返回时永远不会有值。这里的约定是,在错误参数为非空时才返回错误。

标签: objective-c c core-foundation


【解决方案1】:

在Core Foundation 框架中,调用者始终有责任释放通过CFErrorRef * 参数返回的错误。例如这里是来自CFBundle.h的头文件注释:

CF_EXPORT
Boolean CFBundlePreflightExecutable(CFBundleRef bundle, CFErrorRef *error) CF_AVAILABLE(10_5, 2_0);
    /* This function will return true if the bundle is loaded, or if the bundle appears to be */
    /* loadable upon inspection.  This does not mean that the bundle is definitively loadable, */
    /* since it may fail to load due to link errors or other problems not readily detectable. */
    /* If this function detects problems, it will return false, and return a CFError by reference. */
    /* It is the responsibility of the caller to release the CFError. */

AB 框架很可能使用相同的约定。

【讨论】:

  • 头文件中的那条注释直接与the documentation 相矛盾,the documentation 表示所有权遵循创建规则。函数名不包含CreateCopy 中的任何一个,因此调用它时您不会成为所有者。
  • 我会说创建规则的提及不清楚。我倾向于更信任头文件,因为头文件更有可能由创建或维护实际代码的工程师编写。无论如何,CFBundlePreflightExecutable is open source。如果您检查代码,您会发现您确实拥有返回的错误,无论您如何解释文档。
  • 如果您认为应该更改代码以匹配您对文档的解释,file a bug report。如果您认为应该更改文档以更清楚地匹配代码,请单击文档底部的“没有帮助...”链接并让他们知道。
  • 嗯,有趣。我确实单击了“没有帮助...”链接并留下了反馈,所以也许 Apple 会修复它(尽管我没有屏住呼吸)。我绝对不认为更改源代码是一个好主意,因为它会引入大量与现有代码的兼容性问题,我敢肯定。
  • @AdamRosenfield,当文档说某些内容遵循创建规则时,这意味着您应该将其解释为就好像它的名称中有“Create”,即使它没有.它基本上意味着“你获得了这个的所有权”。如果他们没有记录命名约定的例外情况,那么就永远没有理由在文档中调用这些东西(除了最初定义约定的地方)。
【解决方案2】:

根据定义CFErrorRef的“CFError.h”:即

typedef struct __CFError * CFErrorRef; // line 43 in CFError.h

如果你滚动到顶部,你会在第 14 行到第 22 行看到这个:

CFError *error;
if (!ReadFromFile(fd, &error)) {
    ... process error ...
    CFRelease(error);   // If an error occurs, the returned CFError must be released.
}

It is the responsibility of anyone returning CFErrors this way to:
- Not touch the error argument if no error occurs
- Create and assign the error for return only if the error argument is non-NULL

因此看来我们确实需要自己释放 CFErrorRef!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-20
    • 2011-09-28
    • 2012-06-15
    • 2011-05-30
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多