我使用以下代码删除我在地址簿中插入的所有联系人,具体取决于他们已添加到的group
:
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
NSArray* contactsArray = (__bridge NSArray *)(ABGroupCopyArrayOfAllMembers([self ABGetAddressGroup:addressBook]));
if (contactsArray.count) {
for (NSUInteger index = 0 ; index < contactsArray.count; index++) {
ABRecordRef person = (__bridge ABRecordRef)(contactsArray[index]);
ABAddressBookRemoveRecord(addressBook, person, NULL);
}
CFRelease((__bridge CFTypeRef)contactsArray);
NSArray *groups = (__bridge NSArray *) ABAddressBookCopyArrayOfAllGroups(addressBook);
for (id _group in groups) {
NSString *currentGroupName = (__bridge NSString*) ABRecordCopyValue((__bridge ABRecordRef)(_group), kABGroupNameProperty);
if ([[self getDatabase] isEqualToString:currentGroupName]) {
ABAddressBookRemoveRecord(addressBook, (__bridge ABRecordRef)(_group), NULL);
}
CFRelease((__bridge CFTypeRef)(currentGroupName));
}
CFRelease((__bridge CFTypeRef)(groups));
}
if (ABAddressBookHasUnsavedChanges(addressBook)) {//potential leak of an object stored in contactsArray
//Save recent changes
ABAddressBookSave(addressBook, NULL);
} else {
NSLog(@"Nothing to do here, let's eat cake");
}
CFRelease(addressBook);
分析器会在ABAddressBookHasUnsavedChanges
... potential leak of an object stored in contactsArray
中显示警告(如果它被称为“#1}}”。我需要做些什么来摆脱这个?
如果使用CFRelease
如下:
CFRelease((__bridge CFTypeRef)(contactsArray));
分析器说:Reference-counted object is used after it is released
,即使它在非返回方法结束时发布,并且应用程序崩溃。
我在这里做错了什么?如何摆脱这种内存泄漏?
答案 0 :(得分:3)
你的问题就在这一行:
CFRelease((__bridge CFTypeRef)contactsArray);
因为当执行if
语句的true-branch时,此行仅运行 ,因此在其他所有方案中都不会释放contactsArray
。那里纯泄漏。
选项#1
将所有权传递给ARC
:
NSArray* contactsArray = (__bridge_transfer NSArray *)(ABGroupCopyArrayOfAllMembers([self ABGetAddressGroup:addressBook]));
if (contactsArray.count) {
// (...)
// CFRelease((__bridge CFTypeRef)contactsArray);
// (...)
}
选项#2
确保在任何情况下都释放该对象:
NSArray* contactsArray = (__bridge NSArray *)(ABGroupCopyArrayOfAllMembers([self ABGetAddressGroup:addressBook]));
if (contactsArray.count) {
// (...)
// CFRelease((__bridge CFTypeRef)contactsArray);
// (...)
}
if (contactsArray) CFRelease((__bridge CFTypeRef)contactsArray);
这样的事情对你有帮助,我想。