1

マイクアッシュは言う:

キャストで__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二重保持を回避するにはどうすればよいですか?

4

2 に答える 2

1

ClangのドキュメントはMikeAshと一致しています。キャストを実行し、スコープの最後でオブジェクトが解放されることを示しています。キャスト中に実行される保持はありません。

基本的に、呼び出しがタイプのすでに所有されている値を返すのと同じように、(__bridge_transfer T)値をタイプのすでに所有されている値として処理します。T[T new]T

于 2012-07-23T21:36:29.003 に答える
0

「転送」を使用すると、ARCはオブジェクトの保持カウントをその実行の最後にデクリメントします。したがって、この場合、1のカウントから開始しました。「値」は強いのでカウントをインクリメントしますが、「転送」デクリメントが発生するため、1に戻ります。

NSString *value = (__bridge_transfer NSString *)CFStringCreateMutableCopy(NULL, 1000, CFSTR("Hello World") );
NSLog(@"value retainCount %ld", CFGetRetainCount((__bridge CFTypeRef)value));
NSLog(@"Value = %@", value);

2012-07-23 17:45:49.421 TimeTester [75918:f803]値retainCount 1 2012-07-23 17:45:49.423 TimeTester [75918:f803]値= Hello World

于 2012-07-23T21:48:04.293 に答える