この警告を考えてみましょう:
:このブロックで強く
self
をキャプチャ
は、あなたが上記の警告を受信したとき、あなたがあなたのブロックを確認する必要があり サイクルを保持
につながる可能性があります
self
への任意の明示的な参照。または
- への暗黙の参照は、インスタンス変数を参照することによって発生します。
は、我々は(これはあなたの質問と同じ「サイクルを維持する」の警告を経験しますが、少しシンプルな私の例を維持します)ブロックしたいくつかの単純なクラスのプロパティを持っていることを想像してみましょう:
@property (nonatomic, copy) void (^block)(void);
そして、我々は我々がブロック内で使用していたいくつかの他のクラスのプロパティを持っていたと仮定しましょう:
@property (nonatomic, strong) NSString *someString;
あなたは(このプロパティにアクセスするプロセスでは、以下の私の例では)ブロック内self
を参照する場合は、パターンを経由して改善され
self.block = ^{
NSLog(@"%@", self.someString);
};
はあなたが提案、すなわち:明らかに保持サイクルリスクについて警告することを受け取ることになります
__weak typeof(self) weakSelf = self;
self.block = ^{
NSLog(@"%@", weakSelf.someString);
};
はあまり目立たない、あなたも受け取ることになります「サイクルを維持する」場合に警告あなたは、例えば、ブロック内のクラスのインスタンス変数を参照:
self.block = ^{
NSLog(@"%@", _someString);
};
_someString
インスタンス変数は、暗黙的な参照を運ぶためでありますあなたも、ここで弱い自己パターンを採用しようとする傾向があります
self.block = ^{
NSLog(@"%@", self->_someString);
};
、しかし、あなたがすることはできません:self
に、そして実際に相当します。あなたはweakSelf->_someString
構文パターンをしようとすると、コンパイラはこれについて警告します:
__weak
ポインタを間接参照による競合状態によって引き起こされる可能性ヌル値に許可されていない、strong
変数最初
に割り当てそのため、
weakSelf
パターンを使用することによってこの問題を解決するだけでなく、ブロック内のローカル
strong
変数を作成し、インスタンス変数間接参照にそれを使用
:
__weak typeof(self) weakSelf = self;
self.block = ^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"%@", strongSelf->_someString);
// or better, just use the property
//
// NSLog(@"%@", strongSelf.someString);
}
};
ブロック内にあるローカルstrong
参照のstrongSelf
の作成は、他の利点もあります。つまり、完了ブロックが別のスレッドで非同期に実行されている場合は、self
が心配する必要はありませんブロックが実行されている間に割り当てが解除され、意図しない結果が生じます。
ブロックプロパティを扱う場合weakSelf
/strongSelf
パターンは非常に有用であり、あなたはサイクル(別名強い参照サイクル)を保持ないようにしたいが、同時にself
がの実行の途中で割り当てを解除することができないことを確実にすること完了ブロック。
FYI、アップルはのUse Lifetime Qualifiers to Avoid Strong Reference Cyclesセクションの「重要ではないサイクル」の説明でこのパターンについて説明します。
あなたはあなたがあなたの例ではweakSelf.generalInstaImage
を参照し、いくつかの「エラー」を受け取ったことを報告しています。これは、この「保持サイクル」の警告を解決する正しい方法です。警告が表示された場合は、その旨を報告してください。
どのようなエラーが表示されていますか? 'id'か' typeof(self) 'の代わりに実際のクラス名を使ってみてください – Fonix