2013-04-20 106 views
1

我很難在下面的代碼中將CFRelease()調用放在哪裏。如果我將CFRelease()放在一個支架內,它會在另一個支架中抱怨丟失。難以置信CFRelease呼叫

ABMutableMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty); 

if (phones == nil || ABMultiValueGetCount(phones) == 0) { 

    CFArrayRef linkedContacts = ABPersonCopyArrayOfAllLinkedPeople(person); 
    phones = ABMultiValueCreateMutable(kABPersonPhoneProperty); 

    for (int i = 0; i < CFArrayGetCount(linkedContacts); i++) { 

     ABRecordRef linkedContact = CFArrayGetValueAtIndex(linkedContacts, i); 
     ABMultiValueRef linkedPhones = ABRecordCopyValue(linkedContact, kABPersonPhoneProperty); 

     if (linkedPhones != nil && ABMultiValueGetCount(linkedPhones) > 0) { 

      for (int j = 0; j < ABMultiValueGetCount(linkedPhones); j++) { 

       ABMultiValueAddValueAndLabel(phones, ABMultiValueCopyValueAtIndex(linkedPhones, j), NULL, NULL); 
      } 
     } 
    } 

    if (ABMultiValueGetCount(phones) == 0) { 

     return NO; 
    } 
} 

回答

3

正如你可能知道,你必須釋放所有對象,你「自己」,即所有對象 從函數返回名稱中的「創建」或「複製」,但如果只請撥 成功。如果函數返回NULL,則不能在返回的值上調用CFRelease

例如,在你的代碼

ABMultiValueRef linkedPhones = ABRecordCopyValue(linkedContact, kABPersonPhoneProperty); 
if (linkedPhones != nil && ABMultiValueGetCount(linkedPhones) > 0) { 
    // ... 
} 

是目前還不清楚是否在IF塊或不結束呼叫CFRelease(linkedPhones)。 單獨檢查呼叫是否成功可能會更好。

所以你的那部分代碼如下所示:

ABMultiValueRef linkedPhones = ABRecordCopyValue(linkedContact, kABPersonPhoneProperty); 
if (linkedPhones != nil) { 
    for (int j = 0; j < ABMultiValueGetCount(linkedPhones); j++) { 
     CFTypeRef value = ABMultiValueCopyValueAtIndex(linkedPhones, j); 
     if (value != nil) { 
      ABMultiValueAddValueAndLabel(phones, value, NULL, NULL); 
      CFRelease(value); 
     } 
    } 
    CFRelease(linkedPhones); 
} 

我希望這將讓你開始重寫你的全功能分析儀,安全!

+0

感謝您指點我在正確的方向:) – 2013-04-20 16:53:23

+0

@PeterWarbo:不客氣。我懶得「修復」整個功能,但如有必要,請隨時索取更多信息! – 2013-04-20 17:13:33