iOS/Swift-ARC用(1)


改めてARCの概念を明確にしたいと思い、公式文書を見て整理した内容を共有します.
文書リンク:https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html
  • SWIFTは、基本的にARCによってアプリケーションのメモリ使用量を管理します.
  • 一般的に、開発者はあまり気にしなくても正常に動作します.クラスインスタンスが自動的に不要になると、メモリからうまく解放されます.
    しかしARCではできません.アプリケーションのメモリを効率的に管理するためには、開発者がオブジェクトとオブジェクトの関係をより明確に記入する必要があります.これにより、ARCはこれらを把握し、メモリを解除する必要がある場合に解除することができます.
    100 Reference Countingはクラスインスタンスでのみ発生します.構造体や列挙はValue Typeであるため、アドレス値(すなわち参照される情報)は記憶されたり移動されたりしない.

    ARC動作原理


    クラスインスタンスを作成すると、ARCはクラスの参照情報をメモリに割り当てます.
    →インスタンスのタイプ、所有するpropertyなどを保存します.
    また、ARCは、オブジェクトを書き込む必要がなくなると、メモリからオブジェクトを解放します.
    ARCがオブジェクトをメモリから解放するかどうかは、オブジェクトの参照回数が0であるかどうかによって異なります.参照回数が1より大きい場合は、メモリから解放されません.
    →クラスインスタンスを変数または定数に割り当てると、クラスに強い参照が作成されます.強いリファレンスがある限り、メモリから解放されません.

    ARC例

    reference1 = Person(name: "Kevin")
    
    reference2 = reference1
    reference3 = reference1
    ✻Personインスタンスには3つの強い参照があります.
    reference1 = nil
    reference2 = nil
    →参照回数-2→1つ残っているため、Personインスタンスはメモリから解放されないため、Denit{}メソッドは呼び出されません.
    reference3 = nil
    →Denit{}メソッドが呼び出されたときにメモリから解放される

    クラスインスタンス間のStrong Reference Cycle


    上記の例では、ARCが参照回数を追跡すると、参照回数が0に達すると自動的にメモリから解放されます.
    ただし、クラス参照回数は絶対に0に達しない場合があります.
    いつですか.→2つのクラスインスタンスが互いに強いリファレンスを持っている場合、メモリから解放されない強いリファレンスサイクルが発生します.
    class Person {
        let name: String
        init(name: String) { self.name = name }
        var apartment: Apartment?
        deinit { print("\(name) is being deinitialized") }
    }
    
    class Apartment {
        let unit: String
        init(unit: String) { self.unit = unit }
        var tenant: Person?
        deinit { print("Apartment \(unit) is being deinitialized") }
    }
    
    var john = Person(name: "John Appleseed")
    var unit4A = Apartment(unit: "4A")
    2つのインスタンスを作成すると、強いリファレンスは次のようになります.

    john変数はPersonインスタンスに強い参照を持ち、unit 4 A変数はPartmentインスタンスに強い参照を持つ.一つずつ.
    john.apartment = unit4A
    // Person 인스턴스가 Apartment 인스턴스에 대한 strong reference가 1 증가했다
    unit4A.tenant = john
    // Apartment 인스턴스가 Person 인스턴스에 대한 strong reference가 1 증가했다

    →今は2つの強いreferenceがあります.
    john = nil
    unit4A = nil
    このようにしてもメモリから解放されません.
    →無効にしても、次のような強い参照があります.

    しかしjohnがunit 4 aを解除したため、現在はその中のアパートやテナントpropertyに近づく方法がなくなっている.アクセス不可によるメモリ漏洩