2

from: ARC の下に __autoreleasing 所有権修飾子を記述する必要があるのはどのような場合ですか?

  • ( BOOL )save: ( NSError * __autorelease * );

次にコンパイラは、__autoreleasing に設定された一時変数を作成する必要があります。そう:

NSError * e = nil;
[ database save: &error ];

次のように変換されます。

NSError __strong * error = nil;
NSError __autoreleasing * tmpError = error;
[ database save: &tmpError ];
error = tmpError;

さて、変換されたコードは問題なく動作するようです。最後に、効率が「少し」(非常にわずか)であるにもかかわらず、適切に機能することを期待していました。では、わざわざ自動解放を指定する必要はありません。

より正確には。__autoreleasingポインターをポインターに渡すときに使用する必要があることを理解しています。しかし、ほんのわずかなパフォーマンスの向上だけが得られたとしたら、それでは何の意味があるでしょうか。

4

1 に答える 1

1

変数が参照によって渡され、ARC プログラムで割り当てられたときに、このコードで実際に何が起こるかを見逃しています。

非 ARC プログラミングでは、保存関数は次のようになります。

- (BOOL)save:(NSError * __autoreleasing *)myError {
  *myError = [[[NSError error] retain] autorelease]
}

ARC プログラミングでは、保存関数は次のようになります。

- (BOOL)save:(NSError * __autoreleasing *)myError {
  *myError = [[NSError alloc] init];
}

ARC コードがどのように見えるかにかかわらず、両方の保存関数は、保持されて自動解放されたエラー オブジェクトを作成します。

これは、ARC バージョンでは、myError のポインターの型によって、エラー オブジェクトのメモリ管理がどうなるかが決まるためです。実際には、ポインターがタイプ __autoreleasing である限り、*myError 割り当て行は次のように置き換えられます。

*myError = [[[NSError error] retain] autorelease]

実行時に。

したがって、何らかの方法で間違った型のポインタを保存関数に渡すことができた場合、保存関数が間違ったことをする原因になります。

サンプルではコンパイラが一時変数を作成するため、コードはどちらの方法でも機能しますが、最初のバージョンは ARC プログラミングの観点からは意味がありません。

于 2012-09-20T21:48:03.607 に答える