ARC中CFArray的内存泄漏

时间:2012-02-15 16:10:42

标签: iphone cocoa automatic-ref-counting memory-leaks

我使用ARC创建了一个iPhone应用程序,可以访问地址簿中的每个条目,然后是每个人的每个地址。数据存储在CFArrays中,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)”上,突出显示绿色,文本“Thread 1”(不确定这个错误意味着什么)。我也尝试在for循环之前放置CFRelease,但同样的问题也出现了。

如果我删除CFRelease,它会编译,但是在创建addressArray时会出现内存泄漏。有谁知道如何解决这个问题?我似乎无法用ARC来解决这个问题。

2 个答案:

答案 0 :(得分:14)

而不是NSArray *peopleArray =[(__bridge NSArray *) arrayRef copy]; CFRelease(arrayRef);,请使用NSArray *peopleArray = CFBridgingRelease(arrayRef)。这会将对象的所有权转移到ARC。

答案 1 :(得分:3)

每当您在方法名称中看到“复制”时,您应该使用(__bridge_transfer <ObjectType> *)

然后ARC将负责释放对象。

所以你的代码看起来像是:

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