我正在尝试使用该地址簿,但我对内存管理的理解充其量不过如此。

我的项目使用的是自动引用计数(ARC),但据我了解,ARC仅管理Objective-C领域的保留/发布。

我知道我的第一个函数调用:ABAddressBookCreate()返回我“拥有”的ABAddressBookRef,因为我是从名称中带有Create的方法获取它的。完成后,我CFRelease它。

我不了解是ABRecordRef在此方法过程中如何保持 Activity 状态。我应该不必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造成泄漏?

最佳答案

在处理Core Foundation内存管理时,您想参考these ownership policies

问题的关键在于“获取规则”,该条件指出您从中获取的任何CF *对象以及包含单词“获取”的Core Foundation函数,您都不拥有它并且不能保证其使用寿命。重要区别在于“不能保证有效性”和“无效”之间。您可能会引用一个不属于您的对象,但其寿命受到其他来源支持的对象。在这种情况下,您仍然可以使用它而不会崩溃。

从技术上讲,这就是ABRecordRef发生的事情。您尚未拥有它的所有权,但是从记录中获取的ABAddressBookRef很可能拥有它,因此可以保持它的生命。只要该ABAddressBookRef有效,其记录也将有效。如果您要调用CFRelease(iPhoneAddressBook);然后尝试使用该记录,那么我敢打赌它会爆炸。

最后,对于退出问题-是的,您正在按照“创建”规则泄漏ABMultiValueRef,该规则指出您拥有通过包含“创建”或“复制”的函数接收的对象。

10-08 17:53