web-dev-qa-db-ja.com

NSErrorと__autoreleasing

次のサンプルコードブ​​ロックに__autoreleasingを含める目的を誰かに説明してもらえますか?

- (void)execute:(NSError * __autoreleasing *)error {
    // do stuff, possibly assigning error if something went wrong
}

__autoreleasingを削除したところ、すべてが正常にコンパイル/実行されたようです。私はARCの後にobj-cを使い始めたので、これらの二重下線のすべてを実際に学習/理解したことはありません。 ARC移行ガイド を読みましたが、NSErrorの例を完全には理解していません。

37
chinabuffet

ARCがvariablesでどのように機能するかを検討します。各参照変数にはモードがあります(暗黙的または明示的)。strongweakなど。このモードでARCその変数の読み取りと書き込みを処理する方法を知っている。例えばstrong変数の場合、読み取りでは追加のアクションは必要ありませんが、書き込みでは、変数内の既存の参照を解放してから、新しい参照に置き換える必要があります。 ARCが機能するには、変数のモードを知っている必要があります。

次に、それ自体がreferenceによって渡される変数について考えます。 executeの場合、次のように呼び出されます。

NSError *myError = nil;
...
[someObject execute:&myError]; // pass the variable itself by reference, not the variables value

executeの本文には、次の行に沿った割り当てが含まれます。

- (void)execute:(NSError * __autoreleasing *)error
{
   ...
   if (error != NULL)
      *error = [NSError ...]; // assign indirectly via the reference to a variable
   ...
}

ここで、その間接割り当てのために、ARCは参照される変数のモードを知る必要があるため、読み取りと書き込みの方法を認識します。これが__autoreleasingが宣言にあるもので、モードがautoreleasingである変数への参照が渡されたことをARCに伝え、内容を読み書きする方法をARCに伝えます変数の。 __autoreleasingを削除すると、デフォルトのモードが想定されます。この場合は、明示的にすることをお勧めします。

autoreleasingモードは、所有されていない参照が変数に含まれていることを意味します。必要に応じて、読み取りはretainにする必要があり、書き込みは書き込みのみが可能です。これは、主に参照によって渡される変数に使用されます。

上記の例では、変数myErrorのモードがstrong(暗黙的に)であるにもかかわらず、参照によってautoreleasingとして渡されていることに気付くかもしれません-コンパイラがこれを処理します一時的な自動解放変数を導入し、なしをコピーして現在の参照をmyErrorに保持し、一時的な参照をexecute:への引数として渡します。呼び出しが戻った後、コンパイラは一時的なものからmyErrorへの通常の割り当てを行います。これにより、古い参照が解放され、返された参照が保持されます。

詳細については AppleのARCリリースノートへの移行 を参照してください。

コメントのフォローアップ

Q:__autoreleasingは暗黙的に設定されますか?

A:ええと Apple's のドキュメントは特定されていませんが、- Clangのドキュメント は間接的なパラメータに対しては暗黙的であると述べています。上記のように、明確にすることをお勧めしますが、明快さはGood Thing™です。

Q:配置は重要ですか?

A:はい、そしていいえ...これはC宣言であり、クイズの質問(「次の宣言は何を宣言するか」)の内容です。修飾子は2つのアスタリスクの間にある必要がありますオブジェクトへの(型の変数)自動解放ポインタへのポインタですが、Appleコンパイラは「寛容です」 「何を許しているかを具体的に説明する必要はありません。安全にプレーし、適切な場所に置いてください。

Q:間接割り当てを行う前に、errorNULLであることをテストすべきではありませんか?

A:もちろん、間接参照を行う前のどこかにすべきです。示されているコードは単なる概要であり、そのような詳細は...によって省略およびカバーされています。しかし、それが何年にもわたって数回調達されたので、私はあまりに多くを省略したので、適切なifが追加されました。

74
CRD