Утечка памяти с CFArray в ARC - PullRequest
       35

Утечка памяти с CFArray в ARC

1 голос
/ 15 февраля 2012

Я создал приложение для iPhone с использованием ARC, которое обращается к каждой записи в адресной книге, а затем к каждому адресу для каждого человека.Данные хранятся в CFArrays, которые бесплатны и соединены с NSArrays.Код ниже.

ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef arrayRef = ABAddressBookCopyArrayOfAllPeople(addressBook);
NSArray *peopleArray =[(__bridge NSArray *) arrayRef copy];
CFRelease(arrayRef);
arrayRef = nil;

for(id personId in peopleArray)
{
    ABRecordRef person = (__bridge ABRecordRef) personId;
    //process other attributes of the address book

    ABMultiValueRef multi = ABRecordCopyValue(person, kABPersonAddressProperty);
    CFArrayRef addressRef = ABMultiValueCopyArrayOfAllValues(multi);
    NSArray *addressArray = [(__bridge NSArray *) addressRef copy];

    for(NSDictionary *address in addressArray)
    {
       //process the addresses
    }
    CFRelease(addressRef);
    addressRef = nil;
}

Из того, что я исследовал в Интернете и в руководствах Apple по управлению памятью, это выглядит как правильный способ сделать это.Проблема в том, что когда я запускаю код, он останавливается на «CFRelease (addressRef)», выделенном зеленым цветом с текстом «Поток 1» (не уверен, что означает эта ошибка).Я также попытался поместить CFRelease перед циклом for, но возникает та же проблема.

Если я удаляю CFRelease, он компилируется, но при создании addressArray происходит утечка памяти.кто-нибудь знает, как решить эту проблему?Я не могу понять это с помощью ARC.

Ответы [ 2 ]

14 голосов
/ 15 февраля 2012

Вместо NSArray *peopleArray =[(__bridge NSArray *) arrayRef copy]; CFRelease(arrayRef); используйте NSArray *peopleArray = CFBridgingRelease(arrayRef).Это передает право собственности на объект в ARC.

3 голосов
/ 28 августа 2012

Всякий раз, когда вы видите «Копировать» в имени метода, вы должны использовать (__bridge_transfer <ObjectType> *)

Тогда ARC будет отвечать за освобождение объекта.

Таким образом, ваш код будет выглядеть так:

NSArray *peopleArray = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
...