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” において、以下の記述があります。
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
orCFBridgingRetain
casts an Objective-C pointer to a Core Foundation pointer and also transfers ownership to you.
You are responsible for callingCFRelease
or a related function to relinquish ownership of the object.__bridge_transfer
orCFBridgingRelease
moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC.
ARC is responsible for relinquishing ownership of the object.
意訳すると
__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)