我正在尝试使用地址簿,但我对内存管理的理解充其量也是如此。
我的项目正在使用自动引用计数(ARC),但据我所知,ARC只管理Objective-C中的保留/释放。
我理解我的第一个函数调用:ABAddressBookCreate()
返回我“拥有”的ABAddressBookRef,因为我从名称中带有Create
的方法获取它。当我完成它时我CFRelease
。
我不明白是ABRecordRef在此方法过程中如何保持活着状态。我不应该CFRetain
和CFRelease
吗?如果我没有保留/释放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
来创建泄漏?
答案 0 :(得分:5)
在处理Core Foundation内存管理时,您需要引用these ownership policies。
你的问题的关键在于“获取规则”,它指出你获得的任何CF *对象和包含“获取”一词的Core Foundation功能,你不拥有它并且不能保证它是寿命。重要的区别在于“不能保证有效性”和“无效”。您可以引用一个您不拥有的对象,但其生命周期由其他来源支持。在这种情况下,你仍然可以使用它而不会崩溃。
从技术上讲,这是ABRecordRef
发生的事情。你没有获得它的所有权,但是你从获得记录的ABAddressBookRef
极有可能拥有它,因此它保持活着。只要ABAddressBookRef
有效,其记录也有效。如果您打电话给CFRelease(iPhoneAddressBook);
,然后尝试使用该记录,我打赌它会爆炸。
最后,对于您的退出问题 - 是的,您正在根据“创建”规则泄露ABMultiValueRef
,该规则声明您拥有通过包含“创建”或“复制”的功能接收的对象。