Swiftのクロージャ内では常に[unowned self]を使用するべきですか?質問する

Swiftのクロージャ内では常に[unowned self]を使用するべきですか?質問する

WWDC 2014セッション403中級スイフトそしてトランスクリプト、次のスライドがありました

ここに画像の説明を入力してください

講演者は、その場合、そこを使用しないと[unowned self]メモリ リークが発生すると述べました。つまり、常に[unowned self]内部クロージャを使用する必要があるということですか?

の上Swift WeatherアプリのViewController.swiftの64行目、私は を使用しません。しかし、やなどの を[unowned self]使って UI を更新します。私が定義した はすべて なので、問題ないかもしれません。しかし、安全のために、常に を使用するべきでしょうか?@IBOutletself.temperatureself.loadingIndicator@IBOutletweak[unowned self]

class TempNotifier {
  var onChange: (Int) -> Void = {_ in }
  var currentTemp = 72
  init() {
    onChange = { [unowned self] temp in
      self.currentTemp = temp
    }
  }
}

ベストアンサー1

いいえ、 を使用したくない場合もあります[unowned self]。クロージャが呼び出されたときに self がまだ存在することを確認するために、クロージャで self をキャプチャする必要がある場合があります。

例: 非同期ネットワークリクエストの作成

非同期ネットワーク リクエストを作成する場合は、リクエストが終了したときにクロージャを保持する必要がありますself。そのオブジェクトは割り当て解除されている可能性がありますが、リクエストの終了を処理できるようにする必要があります。

いつ使用するunowned selfweak self

またはを本当に使いたいの[unowned self]は、[weak self]強い参照サイクル強い参照サイクルとは、所有権のループが発生し、オブジェクトが(おそらくサードパーティを介して)お互いを所有することになり、両方がお互いの存在を保証しているため、割り当て解除されない状態です。

クロージャの特定のケースでは、その内部で参照される変数はすべてクロージャによって「所有」されることを認識する必要があります。クロージャが存在する限り、それらのオブジェクトは存在することが保証されます。その所有権を停止する唯一の方法は、またはを実行することです[unowned self][weak self]したがって、クラスがクロージャを所有し、そのクロージャがそのクラスへの強い参照をキャプチャする場合、クロージャとクラスの間に強い参照サイクルが発生します。これには、クラスがクロージャを所有するものを所有する場合も含まれます。

具体的にはビデオの例では

スライドの例では、はメンバー変数TempNotifierを通じてクロージャを所有しています。としてonChange宣言しなかった場合、クロージャも を所有し、強い参照サイクルを作成します。selfunownedself

unownedとの違いweak

unownedとの違いは、weakweakOptional として宣言されているのに対し、 は Optional として宣言されてunownedいないことです。 を宣言することで、クロージャ内で nil になる可能性があるケースを処理できるようになります。 nil になっている変数weakにアクセスしようとすると、プログラム全体がクラッシュします。したがって、クロージャが閉じている間は、変数が常に存在すると確信できる場合にのみ使用してください。unownedunowned

おすすめ記事