2013-04-20 98 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