为什么我不需要在此代码中使用CFRetain()ABAddressBookGetPersonWithRecordID()的结果

Mat*_* H. 3 memory-management objective-c ios automatic-ref-counting

我正在尝试使用地址簿,但我对内存管理的理解充其量也是如此.

我的项目使用的是自动引用计数(ARC),但据我所知,ARC只管理Objective-C中的保留/释放.

我理解我的第一个函数调用:ABAddressBookCreate()返回一个我"拥有"的ABAddressBookRef,因为我是从Create名字中的方法获取的.我CFRelease当我是受够了.

我不明白的是ABRecordRef在这个方法的过程中是如何保持活着的.我不应该CFRetainCFRelease它一起吗?如果我没有保留/释放,我在同一个类中有另一个几乎相同的方法崩溃了ABAddressBookRef.

    ABAddressBookRef iPhoneAddressBook = ABAddressBookCreate();    
    ABRecordRef record = ABAddressBookGetPersonWithRecordID(iPhoneAddressBook, self.addressBookRecordID);

    NSString *firstName = (__bridge_transfer NSString*)ABRecordCopyValue(record, kABPersonFirstNameProperty);
    NSString *lastName = (__bridge_transfer NSString*)ABRecordCopyValue(record, kABPersonLastNameProperty);
    NSString *fullName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];

    ABMultiValueRef phoneRef = ABRecordCopyValue(record, kABPersonPhoneProperty);

    // Set up an NSArray and copy the values in.
    NSArray *phoneNumberArray = (__bridge_transfer id)ABMultiValueCopyArrayOfAllValues(phoneRef);


    CFRelease(iPhoneAddressBook);

    // Finally, do stuff with contact information in Obj-C land..
Run Code Online (Sandbox Code Playgroud)

退出的问题:有我创建通过不调用泄漏CFReleaseABMultiValueRef phoneRef就上线?

Mat*_*ing 5

在处理Core Foundation内存管理时,您需要参考这些所有权策略.

您的问题的关键在于"获取规则",其中指出您获得的任何CF*对象和包含"获取"一词的Core Foundation功能,您不拥有它并且无法保证它的生命周期.重要的区别在于"不能保证有效性"和"无效".您可以引用一个您不拥有的对象,但其生命周期由其他来源支持.在这种情况下,您仍然可以使用它而不会崩溃.

从技术上讲,这与您的情况有关ABRecordRef.你有没有考虑它的所有权,但它是极有可能的是ABAddressBookRef,你从得到的记录确实拥有它,因此保持它活着.只要它ABAddressBookRef有效,其记录也将有效.如果您打电话CFRelease(iPhoneAddressBook);然后尝试使用该记录,我打赌它会爆炸.

最后,对于退出问题 - 是的,您正在泄漏ABMultiValueRef"创建"规则,该规则声明您拥有通过包含"创建"或"复制"的功能接收的对象.

  • @ranReloaded,如果他需要在当前范围之外引用该记录,我会无条件地同意你的意见.就目前而言,在各种情况下保持自己摆脱困境仍然是一个很好的建议,但我知道我当然不会保留我需要用于几行的所有CF*对象然后忘记.如果我知道它们归我所拥有的其他CFObject所有,我宁愿保持杂乱无章. (2认同)