iOS桥与bridge_transfer

我很困惑, bridgebridge_transfer ,这是正确的?

 -(void)getData{ ABAddressBookRef addressBook = ABAddressBookCreate(); NSArray *allPeople = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook); NSString *name; for ( int i = 0; i < [allPeople count]; i++ ) { name = (__bridge_transfer NSString *) ABRecordCopyValue((__bridge ABRecordRef)[allPeople objectAtIndex:i], kABPersonFirstNameProperty); } CFRelease(addressBook); allPeople = nil; } 

有谁能解释我如何使用它们?

如果您打开了自动引用计数(ARC),则代码是正确的。

在你的语句中有两个__bridge_transfer 。 结果,创build的CFObjects的所有权将被转移到NSObjects。 如果您打开了ARC,它们将自动释放。 如果您使用__bridge替代这两个语句,则需要显式调用CFRelease来释放由*Copy API创build的CFObjects。

__bridge语句也是正确的。 因为你在CF API中引用了一个NSObject。 你没有转让所有权,所以ARC将把它释放。

这非常简单,当你使用ARC(自动引用计数)时,编译器会负责统计你的variables指向了多less个对象。 当计数到0时,对象被自动分配。 对于来自低层次结构的东西,比如核心基础,编译器不知道该怎么做。 所以如果你只是想告诉编译器“忽略这个,我会在需要的时候释放它”,所以你使用BRIDGE。 或桥传输,如果你想说“把这个作为一个对象,并释放它,当参考变为0)。

当你这样做的时候,你创build一个副本,在正常情况下应该由“CFRelease”释放:

 ABAddressBookCopyArrayOfAllPeople(addressBook) 

但是,通过添加这个,您所有权转移到一个客体c对象:

 NSArray *allPeople = (__bridge_transfer NSArray*)........ 

所以NSArray将由ARCpipe理。


请注意,由于JRG提到,这样做:

 CFRelease(addressBook); 

不pipe怎样都不会影响新创build的对象,而是最初创build的对象仍然需要手动释放:(这很容易分辨,因为这些方法通常在其名称中具有创build复制关键字)


在你的代码中没有发生的事情,但你应该小心的是释放CFRelease的核心基础对象是NULL将导致错误。 正如保罗在评论中提到的那样。

路易斯·奥斯卡我还在研究我对ARC的理解,但我相信addressBook确实需要CFRelease。 ARC不pipe理地址簿。 NSArray * allPeople由ARC通过__bridge_transfer转换提示进行pipe理,并将其作为原始副本创build。 没有CFRelease,addressBook将会泄漏。

一个编辑:我相信在一个零对象上调用CFRelease确实会导致应用程序崩溃