2012-02-15 9 views
1

私は、アドレス帳のすべてのエントリにアクセスし、すべての人物のすべてのアドレスにアクセスするARCを使用してiPhoneアプリケーションを作成しました。データはCFArraysに保存され、フリーダイヤルでNSArraysにブリッジされます。コードは以下の通りです。ARCでのCFArrayによるメモリリーク

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」(このエラーが何を意味するかわからない)です。私はまた、forループの前にCFReleaseを置こうとしましたが、同じ問題が発生します。

CFReleaseを削除するとコンパイルされますが、addressArrayの作成時にメモリリークが発生します。誰もがこの問題を解決する方法を知っていますか?私はARCを使用してそれを把握することはできません。

+0

はどうなりますか? –

+0

これはあなたが意味するものです NSArray * addressArray = [(__bridge __strong NSArray *)addressRef copy]; それはそれを修正するようには見えません... – Mark

+0

いいえ、私はそれをコピーするだけで、それをブリッジしないことを意味します。 –

答えて

14

NSArray *peopleArray =[(__bridge NSArray *) arrayRef copy]; CFRelease(arrayRef);の代わりにNSArray *peopleArray = CFBridgingRelease(arrayRef)を使用してください。これにより、オブジェクトの所有権がARCに転送されます。

+1

チャームのように働いた。あなたは命の恩人です! – Mark

3

あなたはARCは、オブジェクトを解放する責任があります次に(__bridge_transfer <ObjectType> *)

を使用する必要があるメソッド名に「コピー」を見るたびに。

だからあなたのコードは次のようになります。あなたが `__strong NSArray`にそれを埋める場合

NSArray *peopleArray = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); 
関連する問題