5

保持サイクルを避けるためにブロック内で常にweakSelfを使用する必要があると聞いてきましたが、ディスパッチブロックはどうですか?この場合、私の方法は、次のコードで私のサーバーからのエラー応答を処理します。ディスパッチブロックで「weakSelf」を使用する必要がありますか?

//handling server errors (particularly "Token Refresh Failed" ones) 
-(void)handleServerErrorResponse:(NSString *)error { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     UIAlertController *alertController = [DialogHelper getAlertForSimpleAuthError:error]; 
     if ([error isEqualToString:@"Your login session has expired"]) { 
      [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) 
      { 
       [MyModelDataCenter emptyDataCenter]; 
       [MyAPIInterface sharedInstance].authToken = nil; 
       NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; 
       [defaults removeObjectForKey:@"authToken"]; 
       [defaults removeObjectForKey:@"defaultUserObjectDictionary"]; 
       [defaults synchronize]; 
       [AuthenticationHelper sharedInstance].loggedInUser = nil; 
       [self.navigationController popToRootViewControllerAnimated:YES]; 
      }]]; 
     } 
     else { 
      [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]]; 
     } 
     [self presentViewController:alertController animated:YES completion:nil]; 
    }); 
} 

私は他のブロックでそれを行うのと同じこのブロックでweakSelfを使用する必要がありますか。

答えて

8

弱い「ダンス」を使用して、保持サイクルを避ける必要がある永続的な保持サイクルがある場合。それが起こるためには、2つの条件が満たされる必要があります。

  • ブロックがブロック
  • 内で参照されているオブジェクトによって所有され独自の割り当て解除する前にブロックを解放しない所有者

これらのいずれかが真でない場合、永続的な保持サイクルはなく、問題はありません。

この場合、はどちらもではありません。一般的に、ディスパッチキューに置かれたブロックは、ブロックを再利用するためにブロックを囲んでいない限り、保持サイクルの対象にはなりません。

+0

あなたはそれを保持する例を教えてください。 – sbarow

+1

ここに例がありますが、いくつかの中間ステップがあります:http://stackoverflow.com/q/11822476/603977 –

+0

あまりにもよく説明してくれてありがとう!そして例のおかげで! :) – Rafi

5

でも、私が過去に多数、それは(ブロックが参照されたオブジェクトによって保持されていない)必要ない場合selfをweakifyingない理由は、存在しないこと、ジョシュに同意し、非常に最初から合意していますデフォルトで弱くなったself。 (私は、過半数の変化だと思います。)

しかし、selfも何のサイクルが維持されるweakifyない理由があることができます:あなたは長時間実行ブロックによって満たされているインスタンスオブジェクトを持っている

イメージ。ブロックが実行されている間にインスタンスオブジェクトが死ぬ可能性があります。 e。ユーザーが削除したためです。そのような場合、ブロックはそれ以上使用されておらず、モデルから消えてしまったが、ブロックが保持しているので、まだ生きているインスタンスオブジェクトを埋めます。脆弱化すると解放され、キャプチャされたselfnilに設定されます。確認するのは簡単で、通常は何もしません。

しかし、私は実際には考えていないし、このシナリオが「デフォルトで弱める」という経験則を正当化するとは考えていない。

+0

サーバーからの応答を得るために私のAPI呼び出しが遅いインターネット接続のために長い時間がかかる場合、このエラー処理メソッドを持つ 'UIViewController'がポップされると、アプリケーションがクラッシュするということですか? – Rafi

+1

いいえ、私はそれを言っていませんでした。あなたの具体的なコードに依存します。私が言うことは、オブジェクトへの強い参照がある場合、他の誰もそれを参照していないにもかかわらず、オブジェクトの割り当てを解除しません。あなたのアプリでこれが何をするのですか?わかりません。 –

+0

さて、ありがとう、情報ありがとうございます。私はこれらのことを知っているだろう:) – Rafi