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

时间:2012-06-29 21:20:11

标签: objective-c ios memory-management 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..

退出问题:我是否在最后一行未使用CFRelease调用ABMultiValueRef phoneRef来创建泄漏?

1 个答案:

答案 0 :(得分:5)

在处理Core Foundation内存管理时,您需要引用these ownership policies

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

从技术上讲,这是ABRecordRef发生的事情。你没有获得它的所有权,但是你从获得记录的ABAddressBookRef极有可能拥有它,因此它保持活着。只要ABAddressBookRef有效,其记录也有效。如果您打电话给CFRelease(iPhoneAddressBook);,然后尝试使用该记录,我打赌它会爆炸。

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