1. ホーム
  2. スイフト

[解決済み】weak referenceとunowned referenceの違いは何ですか?

2022-04-03 20:40:26

質問

スウィフトは持っています。

  • 強力なリファレンス
  • 弱いリファレンス
  • 未使用のリファレンス

unowned referenceとweak referenceはどう違うのですか?

未所有の参照を使用しても安全なのはどのような場合ですか?

のようなセキュリティリスクはありますか? ダングリングポインタ C/C++の場合?

解決方法は?

両方 weakunowned の参照では strong を保持します (つまり、ARC が参照オブジェクトを解放するのを防ぐために、保持数を増やしたりしません)。

しかし、なぜ2つのキーワードなのでしょうか?この区別は、以下の事実と関係があります。 Optional 型は、Swift言語に組み込まれています。それらについて長い話をします。 任意型 はメモリ安全性を提供します(これは Swift のコンストラクタのルール - は、この利点を提供するために厳密である)。

A weak を参照することで、それが nil (そのため、プログラマは使用する前にそのプロパティの型を確認する義務があります(基本的にコンパイラは、できる限り安全なコードを書くように強制します)。

について unowned になることはないと仮定しています。 nil は、その寿命の間に これは、その参照がチェックなしで安全に使用できる非オプション型として定義されることを意味します。何らかの理由で参照されているオブジェクトが解放された場合、unowned referenceを使用するとアプリがクラッシュします。

から アップルドキュメント :

弱参照は、その参照が有効である場合は常に使用します。 は、その存続期間中のある時点でnilになります。逆に 参照は、一度参照すると決してnilにならないことが分かっている場合です。 が初期化時に設定されます。

ドキュメントには、retain cyclesとそれを破る方法について説明した例がいくつかあります。これらの例はすべて、以下のサイトから抜粋したものです。 ドキュメント .

の例 weak キーワードを使用します。

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
}
 
class Apartment {
    let number: Int
    init(number: Int) { self.number = number }
    weak var tenant: Person?
}

そして、今度はアスキーアートです。 ドキュメントを見る - きれいな図が描かれています)。

Person ===(strong)==> Apartment
Person <==(weak)===== Apartment

PersonApartment の例では、2つのプロパティがあり、両方ともnilであることが許されているが、強い参照サイクルを引き起こす可能性がある状況を示している。このシナリオは、弱い参照で解決するのが最も良い。両方の実体が、他方への厳密な依存関係を持たずに存在することができます。

の例 unowned キーワードを使用します。

class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) { self.name = name }
}
 
class CreditCard {
    let number: UInt64
    unowned let customer: Customer
    init(number: UInt64, customer: Customer) { self.number = number; self.customer = customer }
}

この例では Customer を持つ場合もあれば、持たない場合もあります。 CreditCard がありますが CreditCard は必ず に関連付けられている Customer . これを表現するために Customer クラスには、オプションで card プロパティがありますが CreditCard クラスは、オプションでない(そして所有されていない) customer プロパティがあります。

Customer ===(strong)==> CreditCard
Customer <==(unowned)== CreditCard

CustomerCreditCard の例では、nilが許されるプロパティとnilにできないプロパティが、強い参照サイクルを引き起こす可能性がある状況を示しています。このシナリオは、非所有参照で解決するのが最善です。

Appleからのお知らせです。

弱参照は、変数として宣言する必要があります。 の値は、実行時に変更することができます。弱参照は、以下のように宣言することはできません。 定数

また、3つ目のシナリオとして、両方のプロパティが常に値を持ち、初期化が完了するとどちらのプロパティもnilになることはないはずである。

また、クロージャを扱う上で避けるべき典型的なretain cycleのシナリオもあります。

これについては、ぜひ アップルドキュメント を読むか、または 書籍 .