ARC オブジェクトをキャストする - Automatic Reference Counting
SPECIAL
ARC オブジェクトをキャストする
ARC (Automatic Reference Counting) の管理対象となっているオブジェクトのキャストを行いたい場合は、つぎの 3 通りの方法で行うことができるとのことです。
単純なキャスト
まず、"__bridge" をキャスト後の型指定の前につけて、キャストを行う方法です。
// id 型の "aObject" を void* 型の "obj" にキャストする
void* obj = (__bridge void*)aObject
このとき、変換元の型が retain 可能なポインターであれば変換先はそうでない型を、変換元の型が retain できないポインターであれば変換先は retain できる型を、指定する感じに使うとのことでした。
このキャストによって、制御レベルが変更されたりとか、retain されたりといったことはないようです。
retain を伴うキャスト
つぎに、"__bridge_retained" をキャスト後の型指定の前につけて、キャストを行う方法です。
// id 型の "aObject" を void* 型の "obj" にキャストする
void* obj = (__bridge_retained void*)aObject
このとき、変換元の型には retain 可能なポインターを、変換先の型には retain できないポインターを、指定する必要があるとのことでした。
このとき、変換元のポインターが指すオブジェクトは retain されるとのことなので、retain 可能なオブジェクトを void* ポインターなどに変換して確保しておいて、後で __bridge_transfer で取り出す、といった用途に使用する感じになると思います。
release を伴うキャスト
そして、"__bridge_transfer" をキャスト後の型指定の前につけて、キャストを行う方法です。
// void* 型の "obj" を id 型の "aObject" にキャストする
id aObject = (__bridge_transfer id)obj
このとき、変換元の型には retain できないポインターを、変換先の型には retain 可能なポインターを、指定する必要があるとのことでした。
このとき、変換元のポインターが指すオブジェクトは release されるとのことでしたので、void* ポインターなどに __bridge_retained で確保しておいたオブジェクトを取り出してつかう、といった用途に使用する感じになると思います。
ブリッジキャストの使いどころ
ARC 管理のオブジェクトを void* で渡さないといけない場合などに、この "__bridge_retained" と "__bridge_transfer" を対にして使う感じになるようですね。
これを使えば、オブジェクトを retain して void* に渡すということを "__bridge_retained" という表現でソースコードに盛り込め、取り出す際には void* からオブジェクトを取り出すということを "__bridge_transfer" という表現で盛り込めるところが、便利なように思います。
利用上の注意としては、"__bridge_retained" で ARC 管理外のポインターに変換したまま、それを "__bridge_transfer" で取り出すことを忘れると、参照カウンタが 1 つ増えたままになってしまって、そのオブジェクトが解放されなくなるところでしょうか。
また、"__bridge_transfer" でキャストする先の変数は __strong または __autoreleasing で宣言されている必要があります。__weak や __unsafe_unretained で宣言された変数に "__bridge_transfer" でキャストすると、代入後に直ちにそのオブジェクトが解放されてしまう感じになりました。