0

この質問は以前に尋ねられたことを知っていますが、解決策のどれも私の問題を解決しないので、もう一度質問します。ブロックを介したコールバックの結果として、自分自身でメソッドを呼び出そうとしています。次のエラーが表示されます。

このブロックで「自己」を強くキャプチャすると、保持サイクルが発生する可能性があります

- (void)viewDidLoad {
   [super viewDidLoad];

   self.webClient.completionHandler = ^{
      [self populateData];
   };
}

以下のコードのようなことを試みましたが、それでも同じ警告が表示されます。解決策は何ですか?

__weak id myself = self;
[myself populateData];  
4

2 に答える 2

4

コードは次のようになります。

- (void)viewDidLoad {
   [super viewDidLoad];

   __weak id weakSelf = self;
   self.webClient.completionHandler = ^{
      [weakSelf populateData];
   };
}
于 2012-06-26T16:38:31.023 に答える
0

UIAdam は正しい答えを出しましたが、なぜそれが正しいのかを理解する価値があります。

まず、なぜ警告を受けたのですか?

self には webClient への強い参照があります。webClient には、completedHandler への強い参照があります。completionHandler には、self への強い参照があります。したがって、プログラム内の他のすべての参照がなくなった場合でも、このサイクルの各項目への強力な参照がまだ残っているため、割り当てを解除することはできません。

書き込みの試み

__weak id myself = self;
[myself populateData];  

もちろん機能しません。ブロックは自分自身に割り当てているため、まだ自分自身を参照しています。したがって、ここでは違いはありません。

UIAdam のライティング ソリューション

__weak id weakSelf = 自己; self.webClient.completionHandler = ^{ [weakSelf populateData]; };

は、weakSelf が弱参照であり、ブロックには self への弱参照のみが含まれていることを意味します。したがって、self への他のすべての強い参照がなくなると、弱い参照だけが残ります。弱参照は自己を存続させないため、自己の割り当てが解除されます。

それが起こったとしても、他の何かが webClient への強い参照を持っていて、あなたのブロックが呼び出されたらどうしますか? weakSelf は弱参照であり、オブジェクトの割り当てが解除されると、弱参照は nil に設定されます。したがって、ブロックが呼び出されたときに weakSelf が nil であることを準備する必要があります。本当は書いたほうがいい

id strongSelf = weakSelf;
[strongSelf populatedData];

ブロック内: strongSelf は nil に設定されるか、self に設定されます。ただし、これは強い参照であるため、ブロックが終了するまで非 nil のままになります。そもそも nil でなかった場合。

于 2014-04-03T15:35:36.900 に答える