昨日、私の最新のiOSビルドはXcodeで警告なしで実行されました。バージョン9.3(9E145)に一晩アップグレードした後、複数の警告が表示されました。同様の質問に対して answer(1) に従ってself->score
を試したところ、警告が消えました。
しかし、より最近の answer(2) 同じ質問に対して、設定を変更することで問題が解決されます。現在、Apple LLVM 9.0 - Warnings -Objective C and ARC
の私の設定は
ブロック内の「自己」の暗黙的な保持
しかし、私はBlock implicitly retains 'self'
がコードのコンテキストで何を意味するのか理解していない以下ので、この動作が正しいかどうかはわかりません'意図されました'。または、問題を解決したか、単にそれを隠したか。または、回答1が回答2よりも優れているかどうか。
このコンテキストでのBlock implicitly retains 'self'
の意味を誰かが親切に説明してくれませんか?ありがとう。
score.alpha = 1.0;
if (sequenceState >= STATES_Count)
{
[GraphicScore animateWithDuration:8.0f
delay:1.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^{self->score.alpha = 0.0;} // animations:^{score.alpha = 0.0;}
completion:^(BOOL finished){ }];
}
[self addSubview:score];
self
への暗黙的な参照に関するこの警告は、コードがない場合、強い参照サイクルを導入するリスクがあるブロックとそうでないブロックが必ずしも明確ではないため、役に立ちます。プログラマーにこれらのself
参照を明示的にするように促すことで(Swiftなどの安全なプログラミング言語で必要とされるように)、強力な参照サイクルが潜在的な問題であるかどうかを明確に確認できるコードができあがります。
したがって、警告をオンにしたまま、これらの暗黙のself
参照(ivars)をself->
またはプロパティを使用する場合はself.
で明示的にすることをお勧めします。あなたが参照した最初の回答でアドバイスされているように。
次に、self
クロージャーの個別の使用を確認し、強い参照サイクルの実際のリスクを引き起こさないことを確認できます。そして、もしそうなら、あなたはweakSelf
またはweakSelf
/strongSelf
パターンを適切に採用することができます。
与えられた:
- (void)bobIsYourUncle {
^{score.alpha = 0.0;}();
}
ここで、score
は、self
を介してアクセスされるインスタンス変数です。ブロックはどこかでキューに入れられ、後で実行される可能性があるため、ブロックが作成されたとき、ブロックはself
を保持します。
Ivarアクセス非表示はself
を介して逆参照するため、その暗黙の保持はコードでははっきりとわかりません。コンパイラがivarの前にself->
を追加するというやや醜い提案は、少なくともself
がブロックによってキャプチャされていることを明らかにしています。
だから、はい、それは正しい動作です。そして、はい、それはいつか望まれています。 (ローカル変数で)ブロックが作成される前にivarの値を取得することで回避できますが、そうすることも知っておく必要がありますivarの値が取得される時間を変更します行動の変化。