マイクアッシュは言う:
キャストで__bridge_transferが使用されると、このオブジェクトはすでに保持されており、ARCはそれを再度保持する必要がないことをARCに通知します。ARCが所有権を取得するため、終了時に引き続き解放されます。
Clangのドキュメントによると:
(__bridge_transfer T)opは、保持不可能なポインター型でなければならないオペランドを、保持可能なオブジェクトポインター型でなければならない宛先型にキャストします。ARCは、ローカル値の通常の最適化に従って、囲んでいる完全式の最後に値を解放します。
Clangのドキュメントのどこにも、__bridge_transferが二重保持を回避するとは書かれていません。オブジェクトが将来リリースされることを示しているだけです。
なぜこれが重要なのですか?次のコードスニペットについて考えてみます。
NSString *value = (__bridge_transfer NSString *)CFPreferencesCopyAppValue(CFSTR("someKey"), CFSTR("com.company.someapp"));
CFStringRefは、+1のretainCountで始まります。value
値に割り当てられると、デフォルトで強く参照されるため、CFStringRefは再び保持されます。これにより、二重保持が発生します。スコープの最後で、-releaseがに送信されますが、CFPreferences * Copyvalue
* AppValueからの残りの保持のバランスを取るために他に何も存在しないため、メモリリークが発生します。
__bridge_transfer
二重保持を回避するにはどうすればよいですか?