[ios]__Bridge_transfer 是在一个 NULL 对象上有效吗

标签: ios Objective-C
发布时间: 2017/3/21 23:32:24
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

让我们说一种方法返回 CFErrorRef 通过指针。这返回错误可能是 NULL 。所以可以安全地执行 __bridge_transfer 仍然或应检查 NULL

例如

CFErrorRef cfError;
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, &cfError);

NSError *error = (__bridge_transfer NSError *)cfError;

我看不到任何提到这在文档中和 CFRelease 文件明确规定 This value must not be NULL. https://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFTypeRef/Reference/reference.html#//apple_ref/c/func/CFRelease

解决方法 1:

问题的直接答案是肯定的你可以使用 __bridge_transferNULL 。但这并不是正确的问题。

阅读文档上 ABAddressBookCreateWithOptions 。尤其是,签出的文件 error :

对误差,包含错误的信息。请参阅"地址簿错误"。

这是重要的。

  1. error值在成功的案例没有记录。
  2. errornil / NULL / 0曾经) 不记载。

这不是学术。一些 Api 从历史上看有无效值设置错误。想象一下电话套 CFError-1 。这是"有效的"以来非- NULL 答复意味着你不应该来解释错误,但桥铸造 -1NSError 将会崩溃。

这意味着您必须不触摸 cfError 除非错误由 ABAddressBookCreateWithOptions 返回空值。

CFErrorRef cfError;
NSError *error;
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, &cfError); 
if (addressBookRef == NULL) {
    error = (__bridge_transfer NSError *)cfError;
}

你没问这个问题,但一个附加的皱纹是桥梁不甚至需要的如果编译器识别的东西是 0 相当。例如,此代码会编译,默默地 (假设 _thing1_thing2 是实例变量):

- (id)bar {
    if (_thing1) return NO;
    if (_thing2) return 0;
    return NULL;
}

这就是糟糕的代码,你应该做这是有意的但知道它生成干净...是一件好事来寻找。我跑进一个 bug 造成的这样的事情︰

- (NSNumber *)someCalculationWithError:(NSError *)error {
   return 0; // meant to return @(0)
}
赞助商