我正在尝试使用该地址簿,但我对内存管理的理解充其量不过如此。
我的项目使用的是自动引用计数(ARC),但据我了解,ARC仅管理Objective-C领域的保留/发布。
我知道我的第一个函数调用:ABAddressBookCreate()
返回我“拥有”的ABAddressBookRef,因为我是从名称中带有Create
的方法获取它的。完成后,我CFRelease
它。
我不了解是ABRecordRef在此方法过程中如何保持 Activity 状态。我应该不必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
造成泄漏? 最佳答案
在处理Core Foundation内存管理时,您想参考these ownership policies。
问题的关键在于“获取规则”,该条件指出您从中获取的任何CF *对象以及包含单词“获取”的Core Foundation函数,您都不拥有它并且不能保证其使用寿命。重要区别在于“不能保证有效性”和“无效”之间。您可能会引用一个不属于您的对象,但其寿命受到其他来源支持的对象。在这种情况下,您仍然可以使用它而不会崩溃。
从技术上讲,这就是ABRecordRef
发生的事情。您尚未拥有它的所有权,但是从记录中获取的ABAddressBookRef
很可能拥有它,因此可以保持它的生命。只要该ABAddressBookRef
有效,其记录也将有效。如果您要调用CFRelease(iPhoneAddressBook);
然后尝试使用该记录,那么我敢打赌它会爆炸。
最后,对于退出问题-是的,您正在按照“创建”规则泄漏ABMultiValueRef
,该规则指出您拥有通过包含“创建”或“复制”的函数接收的对象。