2016-08-17 3 views
3

クロージャパラメータを保持する特定のメソッドを「クライアント」に示す方法はありますか?例えばSwiftクロージャパラメータが保持されていることを示します。

、次のコードを持つ:誰でもこのクラスを使用して、それが実際に保持さかされているかどうかについてどんな考えなしの方法whateverにクロージャを渡す開始することができ

import Foundation 

typealias MyClosureType =() -> Void 

final class MyClass { 

    private var myClosure: MyClosureType? 

    func whatever(closure: MyClosureType?) { 
     myClosure = closure 
    } 
} 

を。エラーが発生しやすく、メモリリークにつながる可能性があります。例えば

、このような何かをやって、「クライアント」、私はエラーのこのタイプのを防ぐためにどのような方法があるかどうかを知りたい理由はそれ

final class MyDummyClient { 

    let myInstance = MyClass() 

    func setUp() { 
     myInstance.whatever { 
      self.whateverHandler() 
     } 
    } 

    func whateverHandler() { 
     print("Hey Jude, don't make it bad") 
    } 
} 

を割り当て解除決してされるだろう。私は必要性について、クライアントにヒントを与え、私の方法whateverの定義に追加できるのparamaterのいくつかのタイプがリーク

答えて

2

を避けるためにweakifyするクロージャパラメータがエスケープされるか、非エスケープは、呼び出し側に何らかの指示であるかどうかそれが保持されるかどうか。特に、以外 - エスケープクロージャーパラメータは、関数呼び出しで保持することはできません。 (現在@noescapeマーク)

SE-0103パー、非エスケープ閉鎖このような状況がもう少し明らかになるだろうので、スウィフト3のデフォルトとなり、あなたが閉鎖を保存したい場合は@escapingを記述する必要があります。

それ以外の場合は、ここにあなたを援助する言語機能はありません。 APIの設計とドキュメントでこの問題を解決する必要があります。それがハンドラのようなものなら、プロパティobj.handler = { ... }、またはobj.setHandler({ ... })またはobj.addHandler({ ... })のようなメソッドをお勧めします。こうすれば、コードを読むときに、=またはsetまたはaddのためにクロージャが保存されていることを簡単に知ることができます。 (実際には、約サイクルを保持するユーザーに警告するかどうかを決定する際のObj-C、クランexplicitly looks for methods named set...: or add...:をコンパイルする。これは、同様の診断が将来スイフトコンパイラに追加することができる可能性があります。)

0

と閉鎖自体を提示している特定のケースは保持される唯一のものなので、コールするときにクロージャに[弱い自己]を正しく追加すると問題はありません。

あなたが守ろうとしている問題はわかりませんが、クロージャではなく委任(プロトコル)を使用することもできます。

関連する問題