LoginSignup
0
3

More than 1 year has passed since last update.

Swift メモリ管理

Posted at

Swiftのメモリ管理

Swiftはメモリ管理する際はARC(Automatic Reference Counting)という方法になっている.

ARCとは

オブジェクトが他のオブジェクトから参照されている数を参照カウントとしてゲットしてきて、この参照カウントを追跡してインスタンスを解放をするかどうか判断する。
この参照カウントが一つでもあるとオブジェクトが破棄されることはなくインスタンスは解放されない。
0になった際にオブジェクトは破棄されてガーベジコレクタにいく。
Swiftではオブジェクトが参照した際はデフォルトで強参照になっている。

解放されたかどうかを確かめるには

deinitを使用する。解放されたprintされる。

書き方

class Fish {
  var name: String
    init(name: String) {
        self.name = name
    }

    // デイニシャライザを定義する
    deinit {
        print("deinit!")
    }
}

強参照の循環、循環参照

参照型同士のオブジェクトが参照しあっていると循環参照になり、参照カウントが絶対に1にならないようになってしまう。

class Fish {
  var animal: Animal?
  init() {}

  deinit {
    print("Fishクラスのインスタンスが解放されました")
  }
}

class Animal {
  var fish: Fish?
  init() {}

  deinit {
    print("Animalクラスのインスタンスが解放されました")
  }
}

AnimalクラスとFishクラスが参照しあっているため、どんなに少なくても参照カウントが1となり、メモリが解放されることはなくなってしまう。
また循環参照は別名、強参照の循環とも言われる。

循環参照の解決

手段は2つ
1weak(storyboardでよくみるあれ)
2unowned

class Fish {
  // 弱参照させる
  weak var animal: Animal?
  init() {}
  deinit {
    print("Fishクラスのインスタンスが解放されました")
  }
}

var、letの前にweakをつけることで弱参照にし、参照カウント煮含めないようにする。参照しあっているオブジェクトが他にいなければカウントがゼロになり解放される。

weakに対してunownedはクラスがオプショナル型ではなくnilであることを許容しない場合に使う。

class Fish {
  var animal: Animal?
  init() {}

  deinit {
    print("Fishクラスのインスタンスが解放されました")
  }
}

class Animal {
  unowned var fish: Fish//nilを許容しない
  init() {}

  deinit {
    print("Animalクラスのインスタンスが解放されました")
  }
}

クロージャー内の循環参照

クロージャーもインスタンスなのでクロージャー内でインスタンスを利用する場合は循環参照になる

class Animal {
    let name: String
    init(name: String) {
        self.name = name
    }
    lazy var getInfo: () -> String = { [weak self] in
        return "\(self.name)" // selfの参照カウントが+1になり解放されない
    }
}

Animal→getInfo,getInfo→Animal(self)で循環参照してしまっていたため[weak self]をつける(キャプチャリストという)ことで弱参照にできる。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3