ARC 使用時の __bridge などについて

ARC (Automatic Reference Counting) を使用することによって、 retain や release をコード上明記しなくてよくなりますが、Toll-Free Bridging においては、__bridge などを指定して cast する必要が出てきますが、そこがここ一つ複雑です。

“Transitioning to ARC Release Notes” での記述

Apple のドキュメント、”Transitioning to ARC Release Notes” の “Managing Toll-Free Bridging” において、以下の記述があります。

If you cast between Objective-C and Core Foundation-style objects, you need to tell the compiler about the ownership semantics of the object using either a cast (defined in objc/runtime.h) or a Core Foundation-style macro (defined in NSObject.h):

  • __bridge transfers a pointer between Objective-C and Core Foundation with no transfer of ownership.
  • __bridge_retained or CFBridgingRetain casts an Objective-C pointer to a Core Foundation pointer and also transfers ownership to you.
    You are responsible for calling CFRelease or a related function to relinquish ownership of the object.
  • __bridge_transfer or CFBridgingRelease moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC.
    ARC is responsible for relinquishing ownership of the object.

意訳すると

Objective-C と Core Foundation-style のオブジェクトの間でキャストしたい場合、オーナーシップについてコンパイラに明記する必要がある:

  • __bridge は、Objective-C と Core Foundation との間で、オーナーシップを変更しない場合に使用する。
  • __bridge_retained もしくは CFBridgingRetain は、Objective-C ポインタを Core Foundation ポインタにキャストし、オーナーシップを「ARCから」開発者側に移すために使用する。
    CFRelease を使用してオーナーシップを放棄する必要がある。
  • __bridge_transfer もしくは CFBridgingRelease は non-Objective-C ポインタを Objective-C ポインタに変換するとともに、オーナーシップを「開発者から」 ARC に移すために使用する。
    ARC がオーナーシップを放棄する責任を持つ。

とすると

いろいろ検索すると、参照カウンタをどのようにするかといったことを中心に解説しているページがいくつかありましたが、オーナーシップを移す観点で理解すれば、

  • __bridge は、Objective-C と Core Foundation との間で、その辺りのコードを書いている開発者としてオーナーシップを変更しないでよい、変更するつもりがない場合に使用する。
  • __bridge_retained もしくは CFBridgingRetain は、Objective-C ポインタを Core Foundation ポインタに変換するとともに、オーナーシップをARC管理から外して開発者側に移す、開発者が Core Foundation 上のメモリ管理の責任を持つために使用する。
    なので、CFRelease を使用してオーナーシップを開発者が明確にコーディングして放棄する必要がある。
  • __bridge_transfer もしくは CFBridgingRelease は non-Objective-C ポインタを Objective-C ポインタに変換するとともに、オーナーシップを Core Foundation での開発者の責任から、 ARC 管理下に移すために使用するので、ARC がオーナーシップを放棄する責任を持つ。

ということでよいのでしょうか?

参照ドキュメント

  • Transitioning to ARC Release Notes (2012-07-17)
  • Advanced Memory Management Programming Guide (2012-07-17)
  • Memory Management Programming Guide for Core Foundation (2009-10-21)
カテゴリー: 開発 Tips (41): Framework -- Core Foundation, 開発 Tips (42): Framework -- Foundation タグ: , パーマリンク

コメントは停止中です。