CFRelease(CFArrayRef)崩溃

时间:2013-05-10 12:32:55

标签: ios objective-c abaddressbook core-foundation

我的方法很清楚设备中的地址簿。 方法如下。

-(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方法返回的所有反对意见,其名称包含副本或创建权限?

1 个答案:

答案 0 :(得分:5)

你可能在这里过度释放“人”对象。从一个数组中检索Infact person,它遵循“获取规则”,因此您不是它的所有者而您无法释放它(或者:您可以先保留它然后在您不确定对象时释放它寿命)。在释放“people”的for循环结束时,数组会尝试释放其内部对象(“人员”),这些对象已经过度释放,这会导致崩溃。

因此,尝试删除CFRelease(people)语句,或者作为额外的安全性,在从数组中获取人员后立即添加CFRetain(人员)(但不要删除CFRelease(人员)指令)。