假设一个方法通过指针返回CFErrorRef
。返回的错误可能是NULL
。因此,执行__bridge_transfer
仍然是安全的,或者我应该检查NULL
。
E.g。
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
答案 0 :(得分:3)
您无需检查NULL。
ARC是一种严格的编译时机制。使用__bridge_transfer
时,您只是将变量的内存管理职责转移给编译器。 cfError
在运行时是否恰好为NULL与编译器完全无关。
在您的情况下,ARC会为error
插入一个版本,但如果error
恰好是零,那么这是一个简单的无操作。
答案 1 :(得分:2)
如果函数的返回值为NULL,则错误将为非NULL。
这种CF函数的模式是将错误检查包装在if语句中。
if (addressBookRef == NULL) { /* your error handling here */}
除非非NULL,否则不应尝试桥接任何内容。对象所有权或更准确地保留计数和减少它的责任,对于NULL或nil没有意义。这将是一种反模式。 充其量只是一个空操作。 使用Objective-C将消息发送到nil很好,包括保留和释放。 将NULL值传递给CFRelease()或CGRetain()
是不合适的答案 2 :(得分:1)
问题的直接答案是肯定的,您可以__bridge_transfer
使用NULL
。但这不是正确的问题。
阅读ABAddressBookCreateWithOptions
上的文档。特别是,请查看error
的{{1}}:
出错时,包含错误信息。请参阅“地址簿错误。”
这很重要。
error
未成功记录成功案例的价值。error
nil
/ NULL
/ 0
(永远)未记录在案。这不是学术性的。某些API历来将错误设置为无效值。想象一下,调用将CFError
设置为-1
。那"有效"因为非NULL
回复意味着您不应该解释错误,但是将-1
桥接到NSError
可能会崩溃。
这意味着您不得触摸 cfError
,除非ABAddressBookCreateWithOptions
指示错误返回NULL。
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;
}
这是邋code的代码,我应该不有意识地这样做,但要知道它干净利落地构建......这是一件好事。我遇到了这样的错误:
- (NSNumber *)someCalculationWithError:(NSError *)error {
return 0; // meant to return @(0)
}
答案 3 :(得分:0)
与NSObject不同,向NULL CF对象发送消息是不行的。我不知道具体的桥接转换,但我猜不,使用__bridge_transfer将CF对象转换为NSObject是不行的。
为什么不试试看?将其转换为实例方法的本地范围中的变量。这样,一旦方法超出范围,系统就应该尝试释放对象。