[解決済み] Swiftではクロージャの内部では常に[unowned self]を使うべきか?
質問
WWDC 2014のセッション403にて 中級Swift と トランスクリプト そして、次のようなスライドがありました。
スピーカーは、その場合、もし私たちが
[unowned self]
メモリリークになります。ということは、常に
[unowned self]
をクロージャの中に入れてください。
オン
Swift天気アプリのViewController.swiftの64行目
を使用していない。
[unowned self]
. しかし、私はUIを更新するためにいくつかの
@IBOutlet
のように
self.temperature
と
self.loadingIndicator
. というのは、すべての
@IBOutlet
は、私が定義した
weak
. しかし、安全のために、常に
[unowned self]
?
class TempNotifier {
var onChange: (Int) -> Void = {_ in }
var currentTemp = 72
init() {
onChange = { [unowned self] temp in
self.currentTemp = temp
}
}
}
解決方法は?
を使いたくない場合もあるはずです。
[unowned self]
. 時には、クロージャが呼ばれたときにまだ存在していることを確認するために、クロージャに self を捕捉させたいことがあります。
例 非同期ネットワークリクエストの作成
非同期ネットワークリクエストを行う場合は、以下のようになります。
する
をクロージャに保持させたい。
self
リクエストの終了時のためです。そのオブジェクトは他の方法で割り当て解除されたかもしれませんが、まだリクエストの終了を処理できるようにしたいのです。
を使用する場合
unowned self
または
weak self
を本当に使いたいのはこの時だけです。
[unowned self]
または
[weak self]
を作成する場合です。
強い参照サイクル
. 強力な参照サイクルとは、所有権のループが存在し、オブジェクトが(おそらくサードパーティを通じて)お互いを所有することになり、その結果、お互いがお互いを維持することを保証するため、決して割り当て解除されることがない状態です。
クロージャの場合、その内部で参照されるすべての変数は、クロージャによってquot;own"されることを理解すればよいのです。クロージャが存在する限り、これらのオブジェクトは存在し続けることが保証されています。この所有権を停止させる唯一の方法は
[unowned self]
または
[weak self]
. つまり、あるクラスがクロージャを所有し、そのクロージャがそのクラスへの強い参照をキャプチャしている場合、クロージャとクラスの間に強い参照のサイクルが存在することになります。これは、クラスがクロージャを所有する何かを所有する場合も含まれます。
具体的には、ビデオの例では
スライドの例では
TempNotifier
はクロージャを
onChange
メンバ変数があります。もし
self
として
unowned
を所有し、クロージャは
self
という強力なリファレンスサイクルを構築している。
との違い
unowned
と
weak
との違いは
unowned
と
weak
は、その
weak
がOptionalとして宣言されているのに対し
unowned
はありません。これを宣言することで
weak
を使えば、クロージャの内部でnilになる可能性がある場合にも対処できます。もしあなたが
unowned
変数がたまたまnilであった場合、プログラム全体がクラッシュします。そのため
unowned
クロージャが存在する間、その変数が常に存在することが確実な場合。
関連
-
[解決済み] テスト
-
[解決済み] 型の不変値に変異型メンバを使用することはできません。
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] Swift: print() vs println() vs NSLog()
-
[解決済み] Swiftではクロージャの内部では常に[unowned self]を使うべきか?
-
[解決済み】ARCでブロックに自己の弱参照を必ず渡す?
-
[解決済み】解決方法。iOS 13.0で'keyWindow'が非推奨になりました。
-
[解決済み】プログラムによってナビゲーションのタイトルを変更する
-
[解決済み】Xcode 8 Beta 3 Legacy Swiftを使用する問題
-
[解決済み】swiftでDoubleを最も近いIntに丸めるには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Swift 5でXOR?
-
[解決済み] 型の不変値に変異型メンバを使用することはできません。
-
[解決済み] 純粋な」Swift で弱いプロトコル参照を作るには (@objc なしで) どうしたらいいですか?
-
[解決済み] Swiftでdispatch_onceのシングルトンモデルを使う
-
[解決済み] なぜクラスではなくストラクチャーを選ぶのか?
-
[解決済み】Swift 4でStringのsubstringを使うには?'substring(to:)'は非推奨です。部分的な範囲から'演算子を持つ文字列スライス添字を使用してください。
-
[解決済み】「このアプリケーションはバックグラウンドのスレッドからオートレイアウトエンジンを変更しています」エラーが発生する?
-
[解決済み】weak referenceとunowned referenceの違いは何ですか?
-
[解決済み】swift 4でenumをDecodableにするにはどうすればいいですか?
-
[解決済み】Swiftの`let`と`var`の違いは何ですか?