2012-03-25 6 views
32

bridgebridge_transferと混同していますが、これは間違いありませんか?iOSブリッジとbridge_transfer

-(void)getData{ 
    ABAddressBookRef addressBook = ABAddressBookCreate(); 
    NSArray *allPeople = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook); 

    NSString *name; 
    for (int i = 0; i < [allPeople count]; i++) 
    { 
     name = (__bridge_transfer NSString *) ABRecordCopyValue((__bridge ABRecordRef)[allPeople objectAtIndex:i], kABPersonFirstNameProperty); 
    } 
    CFRelease(addressBook); 
    allPeople = nil; 
} 

私にその使い方を説明できる人はいますか?

答えて

41

自動参照カウント(ARC)をオンにしている場合、コードは正しいです。

お客様の声明には2つの__bridge_transferがあります。その結果、作成されたCFObjectの所有権はNSObjectsに転送されます。 ARCをオンにすると、自動的に解放されます。これらの2つのステートメントの代わりに__bridgeを使用した場合は、*Copy APIで作成されたCFObjectを解放するには、CFReleaseを明示的に呼び出す必要があります。

__bridgeステートメントも正しいです。あなたはCF APIのNSObjectを参照しているからです。あなたは所有権を移譲していないので、ARCはそれを解放します。

+0

thx、「所有権を移譲する」という意味を説明できますか? – Rinat

+8

所有権は、メモリ管理における重要な主要概念です。オブジェクトの「所有者」は、そのメモリを解放する責任があります。これを実行できない場合、オブジェクトはリークします。オブジェクトは複数の所有者を持つことができます。そのため、範囲外になった最後の所有者がこの場合の割り当て解除を行います。 ARCはこれを自動的に行いますが、目的のCオブジェクトに対してのみ自動的に行います。 CoreFoundationオブジェクトはバニラCオブジェクトであるため、コンパイラに対処する方法についてのヒントを与える必要があります。あなたがARCに「所有権を譲渡する」場合、そのオブジェクトの割り当てを解除するのはARCの責任であると言います。 – borrrden

+2

返答が遅れて申し訳ありません。所有権は、主にオブジェクトを解放する責任を負うものです。詳細については、[オーナーシップポリシー](https://developer.apple.com/library/mac/#documentation/CoreFOundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html)を参照してください。 –

19

非常に簡単ですが、ARC(自動参照カウント)を使用すると、コンパイラは変数によってポイントされているオブジェクトの数をカウントします。カウントが0になると、オブジェクトは自動的に取り消されます。コア基盤のような低レベルの構造体から来たもののために、コンパイラは何をすべきかを知らない。コンパイラに "これを無視して、必要なときにリリースします"と伝えたい場合は、BRIDGEを使用します。あなたが「オブジェクトとして扱い、参照が0になったときに解放する」と言う場合は、Bridge転送を使用します)。

通常の状況下では、 "CFRelease" :

ABAddressBookCopyArrayOfAllPeople(addressBook) 

は、しかし、これを追加することによって、あなたはは、Objective-Cのオブジェクトに所有権を移転されています

NSArray *allPeople = (__bridge_transfer NSArray*)........ 

だから、NSArrayのはARCによって管理されます

。 JRGが言及したように、このようにすることをは

注:

CFRelease(addressBook); 
とにかくで新しく作成されたオブジェクトが、その代わりに、あなたはまだ手動で解除する必要がオリジナルのものに影響を与えません

:(それは簡単ですが、伝えるために

)これらのメソッドは通常、 が自分の名前でまたは コピーキーワードを作成してもらうため

起こらない何かあなたのコードでは注意しなければならないのは、CFReleaseでNULLになっているコアの基底オブジェクトを解放するとエラーが発生するということです。パウロが彼のコメントで言及しているように。

+2

'[nil release]'と違って、 'CFRelease(NULL)'はエラーを引き起こします。 – paulmelnikow

+1

はい、あなたが正しいです、http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFTypeRef/Reference/reference.html "cfがNULLの場合、これは実行時エラーを引き起こし、アプリケーションはクラッシュ。" – Pochi

+0

-1: 'NSArray * allPeople =(__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);'返された配列の所有権を転送します。これは 'addressBook'とは関係ありません。それどころか、 'addressBook'は" create "メソッド(' ABAddressBookCreate')で作成されたため、リリースしなければなりません。そうしないと、リークします。 –

1

ルイスオスカーをクラッシュするアプリを与えていない私はまだARCの私の理解を働いているが、私はアドレス帳がCFReleaseを必要としないと考えていnilのオブジェクトにCFReleaseを呼び出すと信じています。 ARCはaddressBookを管理していません。 NSArray * allPeopleは、__bridge_transferキャストヒントを介してARCによって管理されており、元のコピーとして作成されています。 CFReleaseがなければ、addressBookはリークします。

関連する問題