2016-09-16 10 views
2

私は、プロトコルとデリゲートメソッドを使用して、dismissViewControllが呼び出された後に前のVCにデータを戻しています。以下は、それはほとんどのチュートリアルは弱いデリゲートとクラスプロトコル

protocol someVCDelegate { 
    func somefunction() 
} 

var delegate: someVCDelegate! 

を書かれたその方法ではないと私は通常、それを行うだろうかしかし、私はそれを書いて、このクラスの/弱いアプローチに出くわしています。

protocol someVCDelegate : class { 
    func somefunction() 
} 

weak var delegate: someVCDelegate! 

弱いのはARCに関連しており、保持サイクルを回避していることを理解しています。しかし、私がすべての私の場合と同じようにいつ必要なのか分かりません。弱い委任作品を探すことはしません。どのような状況で弱い代表者が必要でしょうか?また、なぜそれが "!"弱いの後、通常それは "?"弱い権利の後に?

+0

いつでもデリゲートをnilにしますか?または前のVCは次のVCへの参照を保持していませんか?オブジェクトが少なくとも1つの強い参照を持っている場合は、ARCはそれをクリーンアップしません。したがって、以前のVCに次のVCへの参照があり、次のVCに前のものへの(強力な)委任参照がある場合、ARCはメモリリークを引き起こす他のすべての参照を失うと削除しません。 – Fonix

+0

代理人とにかく弱いですが、それは難しくなく、将来あなたの頭痛を救うことができます。後で問題になる場合はデバッグするのが難しいかもしれない – Fonix

+0

ただこれを今日読んでください。それは私のためのいくつかの緩やかな終わりを明らかにした:ARC。 https://www.raywenderlich.com/134411/arc-memory-management-swift – Adrian

答えて

2

あなたが言う:

しかし、私はすべての私の例のように、それを必要とする時にわからない、弱いデリゲートをやっていないこと

はあなたが弱いプロトコルデリゲートパターンを必要とする作品強力な参照サイクルの可能性がある場合、つまり一連の強い参照がある場合などです。たとえば、検討:

  • オブジェクトプロパティ(「子」)を有する(「親」)、すなわち、親は子供に強い参照を有します。

  • この子はdelegateプロパティを持ちます。

  • 親のオブジェクトを参照するように子のdelegateを設定します。その場合

、それはデリゲートがweak参照することが重要ですか、他あなたは強い参照サイクルがあるでしょう。

これは簡単な例であり、強力な参照のチェーンが複雑な場合があることに注意してください。たとえば、デリゲートプロパティを持つUIViewサブクラスを考えます。潜在的な強い参照サイクルは、ビューコントローラからそのルートviewまで、一連のサブビューのサブビューを通して、UIViewまで、delegateまで、潜在的にはビューコントローラを参照する可能性があります。その結果、参照サイクルも強くなります。このため、delegateにはweakの参照を使用する傾向があります。

ただし、ビューコントローラ間でデータを渡すためにプロトコルデリゲートパターンを使用すると、プレゼンテーションビューコントローラが提示されたビューコントローラを所有していないため、これは一般的に問題ありません(ビューコントローラの包含を除く) 。ビューコントローラ階層は、一般に、ビューコントローラへの強い参照を維持する。したがって、表示されたView Controllerを閉じると、View Controllerは割り当てが解除され、強力な参照サイクルが解決されます。

多くの場合、私たちは本質的にweakプロトコルデリゲートパターンを採用します(単に、強い参照サイクルがまったく発生しないためです)。しかし、時には強い参照を使用することもあります。最も一般的な強い参照パターンはNSURLSessionであり、そのうちのdelegateは強い参照です。 documentation for init(configuration:delegate:delegateQueue:)として私たちに警告します:

セッションオブジェクトは、あなたのアプリケーションが終了するまでdelegateへの強い参照を保持するか、明示的にセッションを無効にします。 invalidateAndCancel()またはfinishTasksAndInvalidate()メソッドを呼び出してセッションを無効にしないと、アプリケーションは終了するまでメモリをリークします。

これは逆説的に見えるかもしれませんが、この強い参照パターンの利点は、セッションは、それが安全に割り当て解除されたオブジェクトを恐れることなく、そのデリゲートメソッドを呼び出すことができることを知っているということです。 (補足として、NSURLSessionのこの強力なデリゲート動作は、完了ハンドラメソッドを頻繁に使用し、デリゲートメソッドをまったく使用しないため、その醜いヘッドをめったに再現しません。また、デリゲートメソッドを使用すると、 )セッションの代理人としてのビューコントローラよりも)。

要するに、それぞれの状況を評価し、私たちが本能的に傾いている弱い参照が良いかどうかを判断するか、強力な参照でより良いプロトコルが提供されます。

0

なぜ弱いのですか:弱い参照は、それが参照するインスタンスを強く保持しない参照であり、ARCが参照されたインスタンスを破棄しないようにします。この動作は、参照が強い参照サイクルの一部にならないようにします。単に、強い参照ではなく、弱い参照または所有されていない参照としてクラス間の関係のいくつかを定義することによって、強い参照サイクルを解決します。

これは「!」です。それは暗黙のうちにアンラップされているので弱い後。それは価値があるだろう。

プログラムの構造から、オプションの値が最初に設定された後に、その値が常にあることが明白な場合があります。このような場合、オプションの値は常にアクセスされるたびにチェックしたりアンラップする必要がありません。常に値を保持していることが前提です。

関連する問題