2016-05-18 13 views
0

ブロックとクロージャについての明確化が必要です。ブロック/クロージャの理解

  1. ブロックはどのようにオブジェクトを保持しますか?なぜ弱い内側のブロックだけを使う必要があるのでしょうか?私たちがこれに従わなければどうなるでしょうか?または、ブロックを明確にしてください。

  2. 以下は、閉鎖のOSです。

私はこのようなコードを書いています。 favouriteButtonは自己の財産です。

favouriteButton.hidden = false 
dispatch_async(dispatch_get_main_queue(), { 
    self._collectionView.reloadData() 
}) 

エラーはありませんでした。だから私はメインスレッドでUIをやっていると思った。そこで以下のように隠しブロックを無効にするコードを移動しました。

dispatch_async(dispatch_get_main_queue(), { 
    favouriteButton.hidden = false 
    self._collectionView.reloadData() 
}) 

それは閉鎖中プロパティ 'favouriteButton' へ

参照のようなエラーがいずれかの閉鎖を使用する方法について説明してもらえ明示 '自己'

dispatch_async(dispatch_get_main_queue(), { 
    self.favouriteButton.hidden = false 
    self._collectionView.reloadData() 
}) 

が必要で示し/効果的にブロックする。

  1. ブロックとクロージャは同じ方法で機能しますか?

答えて

4

Swift(およびObjective-C)では、ブロックはクロージャです。用語クロージャは、囲みスコープ内の変数の値をキャプチャする個別に実行可能なコードブロックを指します。 Swiftの場合、囲みスコープは通常は関数であり、ブロック内で使用される変数のみがキャプチャされます。

クラスレベルの参照(プロパティと関数呼び出し)をself.にする必要がある理由は、キャプチャを明示的にselfにする必要があるためです。そうすることで、self(または他のオブジェクト参照)がどのようにキャプチャされるかを指定することができます:強(デフォルト)または弱。

ブロック内にオブジェクトを保持する(強い参照を保持する)ことに注意する2つの理由があります。

  1. 最も頻繁に懸念されるのは、保持サイクルを作成することです。これは、ブロックがオブジェクトへの強い参照を保持し、ブロックへの強い参照を保持する場所です。参照の1つが明示的に壊れるまで、ブロックもオブジェクトも解放されません。

  2. ブロック内のオブジェクトを強く参照すると、オブジェクトが意図したよりも長く生きている可能性があります(ブロックを解放すると、キャプチャされた変数が消去されます)。たとえば、あるブロックがナビゲーションスタックからポップされたビューコントローラへの参照を保持している場合、そのブロックが実行されたときに、そのブロックがビューコントローラ上で動作することは望ましくありません。これは、弱い参照をView Controllerに取り込むことで回避できます。これにより、ビューコントローラがポップされたときにビューコントローラの割り当てが解除され、ブロックがノーオペレーションになります。