1. ホーム
  2. objective-c

[解決済み] ARCで__autoreleasing ownership修飾子を記述する必要があるのは、どのような場合ですか?

2022-08-18 02:04:12

質問

パズルを完成させたいのですが、どうすればいいですか?

__strong は、NSObject、NSString などの Objective-C の保持可能なすべてのオブジェクト ポインタのデフォルトです。これは強力な参照です。ARCはそれをバランスよく -release をスコープの末尾につけてバランスをとっています。

__unsafe_unretained は古い方法に等しい。保持可能なオブジェクトを保持せずに弱いポインタに使用されます。

__weak はまるで __unsafe_unretained と似ていますが、自動ゼロ点弱参照であり、参照されているオブジェクトが 解放されるとすぐにポインタが nil に設定されることを意味します。これにより、ポインタのぶら下がりやEXC_BAD_ACCESSエラーの危険性を排除することができます。

しかし、正確には __autoreleasing は何のためにあるのでしょうか?この修飾子を使う必要がある場合について、実用的な例を見つけるのに苦労しています。私は、この修飾子は、次のようなポインタ-ポインタを期待する関数やメソッドにのみ使用されると考えています。

- (BOOL)save:(NSError**);

または

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

で、ARCではこのように宣言しなければなりません。

- (BOOL)save:(NSError* __autoreleasing *);

しかし、これではあまりにも漠然としているので、完全に理解するために なぜ . 私が見つけたコードスニペットは、__autoreleasingを2つの星の間に配置していますが、これは私には奇妙に見えます。型は NSError** (NSErrorへのポインタ-ポインタ)であるため、なぜ __autoreleasing の前ではなく、星の間に置いたのか? NSError** ?

また、他の状況として、私が __autoreleasing .

どのように解決するのですか?

おっしゃるとおりです。公式ドキュメントの説明の通りです。

__autoreleasing で、参照渡し(id *)で、戻り時に自動解放される引数を表します。

これら全ては、非常によく説明されている ARC 移行ガイド .

NSErrorの例では、この宣言は次のことを意味します。 __strong を意味します。

NSError * e = nil;

に変換されます。

NSError * __strong error = nil;

を呼び出すと save メソッドを呼び出します。

- ( BOOL )save: ( NSError * __autoreleasing * );

次に、コンパイラは一時的な変数を作成して __autoreleasing . というわけです。

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

に変換されます。

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

エラーオブジェクトを __autoreleasing として、直接宣言することで回避できます。