1

我很难将我的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;
    }
}
4

1 回答 1

3

您可能知道,您必须释放您“拥有”的所有对象,即从名称中带有“Create”或“Copy”的函数返回的所有对象,但前提是调用成功。如果函数返回NULL,则不能调用CFRelease返回值。

例如,在您的代码中

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

不清楚是否CFRelease(linkedPhones)在 if 块结束时调用。单独检查呼叫是否成功可能会更好。

所以你的那部分代码看起来像:

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

我希望这能让您开始重写您的完整功能 Analyzer-safe!

于 2013-04-20T10:09:29.207 回答