次のサンプルコードブロックに__autoreleasing
を含める目的を誰かに説明してもらえますか?
- (void)execute:(NSError * __autoreleasing *)error {
// do stuff, possibly assigning error if something went wrong
}
__autoreleasing
を削除したところ、すべてが正常にコンパイル/実行されたようです。私はARCの後にobj-cを使い始めたので、これらの二重下線のすべてを実際に学習/理解したことはありません。 ARC移行ガイド を読みましたが、NSErrorの例を完全には理解していません。
ARCがvariablesでどのように機能するかを検討します。各参照変数にはモードがあります(暗黙的または明示的)。strong、weakなど。このモードで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:間接割り当てを行う前に、error
がNULL
であることをテストすべきではありませんか?
A:もちろん、間接参照を行う前のどこかにすべきです。示されているコードは単なる概要であり、そのような詳細は...
によって省略およびカバーされています。しかし、それが何年にもわたって数回調達されたので、私はあまりに多くを省略したので、適切なif
が追加されました。