iOS bridge vs bridge_transfer

Rin*_*nat 33 objective-c ios automatic-ref-counting

我很困惑与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;
}
Run Code Online (Sandbox Code Playgroud)

有没有人可以解释我如何使用它们?

He *_*ing 42

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

__bridge_transfer你的陈述中有两个.因此,创建的CFObjects的所有权将转移到NSObjects.如果您打开了ARC,它们将自动释放.如果您使用__bridge这两个语句,则需要显式调用CFRelease以释放API创建的CFObject *Copy.

__bridge说法也是正确的.因为您在CF API中引用了NSObject.您没有转让所有权,因此ARC将其释放.

  • 所有权是内存管理中的一个重要关键概念.对象的"所有者"负责释放其内存.如果它不能这样做,对象将泄漏.但是,对象可以拥有多个所有者,因此在此情况下,超出范围的最后一个所有者负责释放.ARC会自动执行此操作,但仅适用于Objective-C对象.CoreFoundation对象是vanilla C对象,因此您需要为编译器提供有关如何处理它们的提示.如果您将所有权"转让给ARC",则表示ARC有责任解除分配对象. (8认同)
  • 很抱歉迟到了.所有权主要是关于谁负责释放对象.如果您需要详细信息,请参阅[所有权政策](https://developer.apple.com/library/mac/#documentation/CoreFOundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html). (2认同)

Poc*_*chi 19

它非常简单,当您使用ARC(自动引用计数)时,编译器将负责计算变量指向的对象数.当计数变为0时,对象将自动被处理.对于来自低级结构的东西,比如核心基础,编译器不知道该怎么做.所以你使用BRIDGE,如果你只想告诉编译器"忽略这个,我将在需要时释放它".如果你想说"将此作为一个对象处理并在引用变为0时释放它",则转换为桥接器.

执行此操作时,您创建的副本在正常情况下应由"CFRelease"释放:

ABAddressBookCopyArrayOfAllPeople(addressBook)
Run Code Online (Sandbox Code Playgroud)

但是,通过添加此项,您所有权转移到objective-c对象:

NSArray *allPeople = (__bridge_transfer NSArray*)........
Run Code Online (Sandbox Code Playgroud)

所以NSArray将由ARC管理.


请注意,正如JRG所提到的,这样做:

CFRelease(addressBook);
Run Code Online (Sandbox Code Playgroud)

无论如何都不会影响新创建的对象,而是您仍然需要手动释放的原始对象:(很容易辨别,因为这些方法通常在其名称中包含createcopy关键字)


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

  • 与`[nil release]`不同,`CFRelease(NULL)`会导致错误. (2认同)