ここには 2 つの問題があります。1 つ目は、@bbum によって既に指摘されているタイミングの問題です。
もう 1 つは、コンパイラがそのようなエラーを出す理由など、あなたが求めていることかもしれません。また、@bbumが言ったように、「コンパイラのメッセージは紛らわしい」。invokeSyncAndWait:
最初の問題から 2 番目の問題を分離するために、呼び出しがではなく であると仮定しましょうinvokeAsync:
。タイミングの問題はなくなり、2 番目の問題に集中できます。
NSError* error = nil;
[self invokeSyncAndWait:^id{
return [self doSomething:&error];
}];
ブロックでキャプチャされたerror
変数は値によるコピーであり、実際の参照ではありません。
囲んでいるレキシカル スコープにローカルなスタック (非静的) 変数は、const 変数としてキャプチャされます。それらの値は、プログラム内のブロック式のポイントで取得されます。ネストされたブロックでは、値は最も近い外側のスコープから取得されます。
ブロック内の変数への実際の参照error
がないため、そのアドレスを取得できません。これが、コンパイラがコードのコンパイルを拒否する理由です。
参照変数を取得するには、次を使用する必要があります__block
。
__block ストレージ修飾子で宣言された囲んでいるレキシカル スコープに対してローカルな変数は、参照によって提供されるため、変更可能です。同じ囲みレキシカルスコープ内で定義された他のブロックを含め、すべての変更は囲んでいるレキシカルスコープに反映されます。これらについては、「__block ストレージ タイプ」で詳しく説明しています。</p>
したがって、作業コードは次のとおりです。
__block NSError* error = nil;
[self invokeSyncAndWait:^id{
return [self doSomething:&error];
}];
ただし、それでも危険なコードです。
したがって、__block 変数のアドレスは時間の経過とともに変化する可能性があります。
コンパイルの問題を説明しました。