20

メモリをクリアするために Core Foundation オブジェクトを解放する必要がありますか? もしそうなら、どのように?

たとえば、コードでは次のようになります。

ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef peopleArray = ABAddressBookCopyArrayOfAllPeople(addressBook);

リリースする必要がありpeopleArrayますか? どうaddressBookですか?

4

5 に答える 5

26

はい、CoreFoundation では、名前に Create または Copy を含むものをすべてリリースする必要があります。これは CFRelease() で行います。あなたの場合、配列とアドレス帳の参照の両方を解放する必要があります。

于 2009-05-15T18:50:28.673 に答える
26

Core Foundation のメモリ管理の規則は、Cocoa の規則と似ています。参照を返すメソッドに「作成」または「コピー」という単語が含まれている場合、CFRelease()その参照を所有しており、その参照を呼び出して所有権を放棄する必要があります。それ以外の場合は、参照を所有していないため、所有権を取得するために呼び出す必要があります (必然的に、その新しい所有権を放棄CFRetainするために後続が必要になります)。CFReleaseこれらのルールは、Core Foundation のメモリ管理プログラミング ガイドから抜粋したもので、次のとおりです。

  • オブジェクトを (直接または別のオブジェクトのコピーを作成することによって) 作成すると、そのオブジェクトの所有者になります。
  • 他の場所からオブジェクトを取得した場合、あなたはそれを所有していません。破棄されないようにしたい場合は、(CFRetain を使用して) 自分自身を所有者として追加する必要があります。
  • オブジェクトの所有者である場合は、(CFRelease を使用して) オブジェクトの使用が終了したら、所有権を放棄する必要があります。

あなたの例では、 と の両方をリリースaddressBookするpeopleArray必要があります。Core Foundation には同等のものがないためautorelease、メソッドから参照を返す場合は、配列を解放せずに返します。(悪意を持っていない限り) メソッド名に「create」を含めて、返されたオブジェクトへの参照を所有していることを呼び出し元に示す必要があります。この場合、CFArray は、NSCFArrayから継承する Objective-C オブジェクトである に無料でブリッジされNSObjectます。したがって、関数/メソッドから返す必要がある場合はpeopleArrayNSArray*andにキャストできます。autorelease

return [(NSArray*)peopleArray autorelease];

これは、無料のブリッジ クラスでのみ機能することに注意してください。私の理解では、独自の無料のブリッジ クラスを作成するのはかなり難しく、プリミティブ (文字列、配列など) CF クラスのみが無料でブリッジされるため、このアプローチは常に機能するとは限りません。最後に、使用を避けることができればautorelease(つまり、メモリ管理をより明示的にすることができれば)、それはおそらく常に良いことです。

于 2009-05-15T18:51:53.477 に答える
4

まだ誰も言及していないもう1つの小さな点として、一部のCFクラスには、NSクラスとの「フリーダイヤルブリッジ」があります。CFStringおよびNSStringCFArrayおよびNSArrayは両方とも例です。releaseこれらのクラスで使用できるので、これは適切です。

詳細については、この他のStackOverflowの質問を参照してください。

于 2009-05-15T19:08:46.103 に答える
3

ARCの場合は使用できます。

return (__bridge_transfer NSArray*)peopleArray;

「__bridge_transfer」は所有権をARCに譲渡するため、これ以上リリースを呼び出す必要はありません。

于 2012-05-05T20:14:50.490 に答える
3

これについての詳細な議論については、Core Foundation のメモリ管理に関するApple のガイドを読むことをお勧めします。一般的な Cocoa メモリ管理についても同様のガイドがあります。

CF オブジェクトを解放するには、CFRelease関数を呼び出します。

于 2009-05-15T18:51:33.647 に答える