IOS ObjectC weakSelf strongSelf使用シーン

1981 ワード

Objective CのBlockは実用的な構文で、特にGCDと組み合わせて使用すると、同時・非同期トランザクションを容易に実現できます.ただし、呼び出しが適切でない場合、Blockはいくつかのループ参照の問題を引き起こすこともあります.BlockretainselfそしてselfまたretainBlock.ObjCでは、インスタンス変数を直接呼び出すため、コンパイラによって処理されるself->propertyselfはstrongタイプの変数であり、参照カウントに1が加算されるため、self retains queue, queue retains block,block retains self.
  • ステップ①retain circleの解決


  • Apple公式の提案は、Blockに伝える前に、selfをweak automaticの変数に変換することで、Blockではselfへの強い引用は現れない.Block実行が完了する前にselfが解放されるとweakSelfもnilになります.
    Appleの公式の提案は、Blockに伝わる前に「self」をweak automaticの変数に変換し、Blockでselfへの強い参照が現れないことだ.Blockの実行が完了する前にselfが解放されるとweakSelfもnilになります.
    コードデモ
    
    //ObjectC code
    
    #define Up_WeakSelf_wsf  __weak typeof(self) wsf = self
    
    #define Up_StrongSelf_ssf  __strong  typeof(self) ssf = wsf; if (nil == ssf) return
    
    Up_WeakSelf_wsf;
    
    dispatch_async(dispatch_get_main_queue(), ^{
    
    [wsf doAction];
    
    });
    
    

    clangのドキュメントは、doSomething内でweakSelfが解放されないことを示しています.ただし、次の場合を除きます.
    
    //ObjectC code
    
    Up_WeakSelf_wsf;
    
    dispatch_async(dispatch_get_main_queue(), ^{
    
      [wsf doAction];
      [wsf doOtherAction];
    });
    
    
  • ステップ②BlockにおけるweakSelfの複数回のセキュリティコールの解決


  • doActionではwsfはnilにはなりませんが、doActionの実行が完了し、2番目のメソッドdoOther Actionが呼び出されると、マルチスレッド環境でweakSelf[wsf]が解放される可能性があります.この場合、strongSelfが役に立ちます.
    
    //ObjectC code
    
    Up_WeakSelf_wsf;
    
    dispatch_async(dispatch_get_main_queue(), ^{
      Up_StrongSelf_ssf;
    
      [ssf doAction];
      [ssf doOtherAction];
    });
    
    

    *__strongはBlock内でstrongSelfが解放されないことを保証する.
    まとめ:
  • Block内でselfに1回アクセスする方法、属性、変数が必要な場合はweakSelfを使用することを推奨します.
  • Block内でselfに複数回アクセスし、安全を確保する必要がある場合はstrongSelfを使用する必要がある.

  • weakSelf
    strongSelf
    シングルコール
    マルチコール
    作者@iSagehttps://github.com/WSFeng
    2017年01月08日18:51:00