taffarel
taffarel

Reputation: 4045

Crash when CFRelease(CFArrayRef)

I have method which is clear the adress book in the device. the method is below.

-(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);
}

when I'm releasing CFArrayRef application crashes, what is wrong here? As i know i have to release all objected returned from CF methods which names contains copy or create right ?

Upvotes: 2

Views: 3538

Answers (1)

viggio24
viggio24

Reputation: 12366

You are probably over-releasing here the "person" object. Infact person is retrieved from an array and it follows the "get rule" so you're not the owner of it and you cannot release it (or: you can first retain it and then release it if you're not sure of the object life span). At the end of the for-loop when you release "people", the array tries to release its internal objects ("people") which have been over-releases and this leads to the crash.

So try to remove the CFRelease(people) statement or, as extra safety, add a CFRetain(people) immediately after you fetch person from the array (but then don't remove the CFRelease(people) instruction).

Upvotes: 5

Related Questions