我的方法很清楚设备中的地址簿。 方法如下。
-(void) clearAdressBook
{
ABAddressBookRef addrBook=ABAddressBookCreate();
CFArrayRef groups = ABAddressBookCopyArrayOfAllGroups(addrBook);
if(groups)
{
CFIndex numGroups = CFArrayGetCount(groups);
for(CFIndex idx=0; idx<numGroups; ++idx)
{
ABRecordRef groupItem = CFArrayGetValueAtIndex(groups, idx);
CFArrayRef people=
ABGroupCopyArrayOfAllMembers(groupItem);
if(people)
{
CFIndex peopleCount=CFArrayGetCount(people);
for(CFIndex ind=0;ind<peopleCount;++ind)
{
ABRecordRef person=CFArrayGetValueAtIndex(people, ind);
ABAddressBookRemoveRecord(addrBook, person, nil);
ABAddressBookSave(addrBook, NULL);
CFRelease(person);
}
CFRelease(people);//CRASH
}
}
}
CFRelease(groups);
}
当我发布CFArrayRef应用程序崩溃时,这里有什么问题?据我所知,我必须释放从CF方法返回的所有反对意见,其名称包含副本或创建权限?
答案 0 :(得分:5)
你可能在这里过度释放“人”对象。从一个数组中检索Infact person,它遵循“获取规则”,因此您不是它的所有者而您无法释放它(或者:您可以先保留它然后在您不确定对象时释放它寿命)。在释放“people”的for循环结束时,数组会尝试释放其内部对象(“人员”),这些对象已经过度释放,这会导致崩溃。
因此,尝试删除CFRelease(people)语句,或者作为额外的安全性,在从数组中获取人员后立即添加CFRetain(人员)(但不要删除CFRelease(人员)指令)。