2016-04-25 8 views
0

私のカスタムUIViewControllerサブクラスには、格納されたクロージャプロパティがあります。閉鎖署名はクラスの同じタイプの単一の引数を取るように定義される: キャプチャリストを使用して参照サイクルを回避する方法に関する混乱

class MyViewController { 

    var completionHandler : ((MyViewController)->(Void))? 

    // ... 
} 

...アイデアであり、ハンドラの引数、ビットlike the UIAlertAction initializerとして自身をバック通過オブジェクト。また

、及び便宜のために、私は工場(-ish)クラスメソッドがあります。それは次の処理を実行

class func presentInstance(withCompletionHandler handler:((MyViewController)->(Void))) 
{ 
    // ... 
} 

に...:

  1. ビューのインスタンスを作成しコントローラー
  2. プロパティに完了ハンドラーを割り当てます。
  3. 呼び出し時にトップ/ルートビューコントローラーになることをモーダルで示します。

私のビューコントローラは間違いなく漏れている:を私はdeinit()にブレークポイントを設定するが、実行は、私は私のビューコントローラで行わことだし、それが却下されても仕方の後に、それを打つことはありません。

サイクルを回避するために、キャプチャリストを指定する方法や場所がわかりません。私が見てきたすべての例は、クロージャー本体が定義されている場所に配置されているようですが、コードをコンパイルすることはできません。

  1. ここで私はクロージャプロパティを宣言しますか? (どう?)

    var completionHandler : ((MyViewController)->(Void))? 
    // If so, where does it go? 
    
  2. ここで私はクロージャパラメータを宣言していますか?

    class func presentInstance(withCompletionHandler handler:((MyViewController)->(Void))) 
    { 
    // Again, where could it go? 
    
  3. ここで私は上記の関数を呼び出してクロージャー本体を渡しますか?

    MyViewController.presentInstance(withCompletionHandler:{ 
        [unowned viewController] viewController in 
    
        // ... 
    }) 
    //^Use of unresolved identifier viewController 
    //^Definition conflicts with previous value 
    
  4. selfに向けた私は実際にコール閉鎖、?これらの どれもコンパイルされません:

    self.completionHandler?(unowned self) 
    self.completionHandler?([unowned self] self) 
    self.completionHandler?([unowned self], self) 
    

答えて

0

をまあ、それは私が考えていた1私のビューコントローラは、ブロックによって保持されていたが判明、しかしない:

class MyViewController 
{ 
    deinit(){ 
     print("Deinit...") 
    } 

    // ... 

    @IBAction func cancel(sender:UIButton) 
    { 
     completionHandler(self) 
     // View controller is dismissed, AND 
     // deinit() gets called.  
    } 

    @IBAction func punchIt(sender: UIButton) 
    { 
     MyWebService.sharedInstance.sendRequest( 
      completion:{ error:NSError? in 

       self.completionHandler(self) 
       // View controller is dismissed, BUT 
       // deinit() does NOT get called. 
      } 
     ) 
    } 

を...それで、MyWebService.sharedInstance.sendRequest()に渡されたクロージャが、私のView Controllerを生き生きとさせていました。私はこのようなキャプチャリスト追加することによって、それを修正:

MyWebService.sharedInstance.sendRequest( 
      completion:{ [unowned self] error:NSError? in 

しかし、私はまだ非常に理解していないが、なぜWebサービスクラスに渡さ短命完了ハンドラ、一度実行され、配置され、私のView Controllerを生かしていました。プロパティとして格納されていないクロージャは、終了すると即座に解放されますか?

私は何かが欠けているはずです。私はまだ完全にポータルで考えていないと思いますクロージャ。

関連する問題