2016-08-28 5 views
1

とObserverパターンIは、関数のみを使用して迅速でObserverパターンを実装しようとしている:これは印刷しスウィフト、閉鎖

var closures: [() -> Void] = [] 

class A: NSObject 
{ 
    static var c = 0 
    var i = 0 

    override init() 
    { 
     super.init() 
     self.i = A.c 
     A.c += 1 
    } 

    func foo() 
    { 
     print("Hi: \(i)") 
     print("\(A.c)") 
    } 
} // class 

var aa:A? = A() 

closures.append(aa!.foo) 

for item in closures 
{ 
    item() 
} 

aa = A() 

for item in closures 
{ 
    item() 
} 

Hi: 0 
1 
Hi: 0 
2 

最初の質問を、それはインスタンス変数のように見えますiは決して変更されません、あなたはその理由を知っていますか?

2番目の質問は、メモリがリークですか?私は配列の配列を持っているので、配列を空にしないでaaが解放されますか?

3番目の質問は、関数を使用したObserveパターンの方が良いでしょうか? (私はプロトコルを使用したくない)

答えて

0

私はGoogleでより良いキーワードを使用して解決策を見つけました。 私は、プロトコルを避けるためにクロージャを使ってオブザーバパターンを実装する必要があったため、オブザーバとオブザーバを切り離す必要がありました。 観察者は、このようなクロージャの配列を持つオブジェクトです: var array:[() ->()] = []

各観察可能な、それは観察者がそれぞれまたはこの配列の任意の関数を呼び出します必要なのは、この配列への関数の追加します。 機能は以下のようになります。

lazy var someClosure:() -> String = { [unowned self, ] in // closure body goes here } selfunowed又はweakとして捕捉されなければならないサイクルを維持回避します。ここで

は詳細にこのソリューションをexaplain記事です:https://medium.cobeisfresh.com/why-you-shouldn-t-use-delegates-in-swift-7ef808a7f16b#.dmijmxbc4

1

あなたは、保持/解放のサイクルを誤解していました。

var aa:A? = A() 

Aの新しいインスタンスを初期化してください。このメモリはclosuresアレイにAのインスタンスを追加1.

closures.append(aa!.foo) 

の保持カウントを有します。保持カウントはAの最初のインスタンス上の2

for item in closures 
{ 
    item() 
} 

コールfooです。

aa = A() 

Aの別のインスタンスを作成します。最初のインスタンスは引き続きアレイに保持され、保持カウントは1に低下しますが、initメソッドでコード化したため、A.cがインクリメントされます。

for item in closures 
{ 
    item() 
} 

あなたはまだ最初のオブジェクトのメソッドを呼び出しています。 A.cは2番目のオブジェクトと共有されますが、iは共有されません。 2番目のオブジェクトは決してclosures配列にありません。

他の質問が出る前に、どうしたのですか?

+0

私は「なぜ」 '何であると思います。私はタイプを使用せずにObserverパターンを実装しようとしています。クラスAのようなオブジェクトは配列に関数を追加します。必要に応じて、配列の各関数が呼び出されます。私はプロトコルを使って同じことをすることができましたが、私は別のものを試してみたかったのです。 – AR89