2013-05-10 5 views
2

장치에서 주소록을 지우는 방법이 있습니다. 방법은 다음과 같습니다.CFRelease (CFArrayRef)

-(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

흠. [documentation] (http://developer.apple.com/library/ios/documentation/AddressBook/Reference/ABGroupRef_iPhoneOS/Reference/reference.html#//apple_ref/c/func/ABGroupCopyArrayOfAllMembers)에 따르면, 배열, 그래서 이미 autoreleased있어? 사람들을 석방하지 않으면 메모리 누수가 발생합니까? –

+0

프로파일 러는 모든 것이 정상이며 메모리 누수가 없음을 보여줍니다. – taffarel

답변

4

"사람"개체를 여기에서 너무 많이 공개하고 있습니다. Infact 사람은 배열에서 검색되고 그것은 "규칙을 얻을"그래서 당신이 그것의 소유자가 아니므로 당신은 그것을 풀 수 없습니다 (또는 : 당신이 먼저 그것을 유지하고 당신이 개체의 확실하지 않으면 그것을 풀어 수 있습니다 수명). for-loop의 끝에서 "people"을 릴리즈 할 때 배열은 over-release 된 내부 객체 ("people")를 해제하려고 시도하며 충돌이 발생합니다.

그래서 CFRelease (people) 명령문을 제거하려고 시도하거나 추가 안전성으로 배열에서 사람을 가져온 직후 CFRetain (people) 명령을 제거하십시오. 그러나 CFRelease (people) 명령은 제거하지 마십시오.

+0

나는 심지어 그것을 알아 차리지 못했다. 좋은 캐치. –

+0

CFRelease (사람)을 제거했습니다. CFRelease (people)를 다시 넣으십시오. 이제는 잘 작동합니다. 감사. – taffarel

+0

2 년 전이지만 유용한 힌트를 주셔서 감사합니다. 나는 "over-release"가 ... getMatchingServices()를 사용한 후에 내 문제가 풀리는 것을 보았을 때까지 나의 충돌을 알아낼 수 없었다. –