Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swiftでなんで[weak self]するのか?

oyuk
April 05, 2018
4.1k

Swiftでなんで[weak self]するのか?

oyuk

April 05, 2018
Tweet

Transcript

  1. weak selfについて よくあるアレ { [weak self] event in guard let

    strongSelf = self else { return } // なんかする } 3
  2. 参照カウント 例2 class Hoge {} // Hoge のインスタンスの参照カウントが1 になる var

    h: Hoge? = Hoge() // Hoge のインスタンスの参照カウントが0 になり解放される h = nil 10
  3. 参照カウント 例3 class Hoge { var fuga: Fuga? } class

    Fuga { var hoge: Hoge? } var hoge: Hoge? = Hoge() // hoge の参照カウント1 var fuga: Fuga? = Fuga() // fuga の参照カウント1 hoge.fuga = fuga // hoge の参照カウント2 fuga.hoge = hoge // fuga の参照カウント2 hoge = nil // hoge の参照カウント1 fuga = nil // fuga の参照カウント1 hoge も fuga も参照することができないのにメモリ上に残ったままになっている hoge と fugga で循環参照が起きている 11
  4. 参照カウント 例4 class Hoge { private var closure: (() ->

    Void)? private var count = 0 init() { closure = createClosure() } func createClosure() -> (()-> Void) { return { self.count += 1 } } } var h: Hoge? = Hoge() // Hoge の参照カウント2 , closure の参照カウント1 h = nil // Hoge の参照カウント1 hoge と closure で循環参照が起きている 12
  5. 循環参照 var h: Hoge? = Hoge() // Hoge の参照カウント2 ,

    closure の参照カウント1 h = nil // Hoge の参照カウント1 13
  6. 循環参照解決策 class Hoge { private var closure: (() -> Void)?

    private var count = 0 init() { closure = createClosure() } func createClosure() -> (()-> Void) { return { [weak self] in self?.count += 1 } } } var h: Hoge? = Hoge() // Hoge の参照カウント1 , closure の参照カウント1 h = nil // Hoge の参照カウント0 解放される! 14
  7. なぜ func createClosure() -> (()-> Void) { return { [weak

    self] in self?.count += 1 } } [weak self] は self を参照するが参照カウントは+1しないという意味 これが弱参照 ちなみに今までのは強参照 循環参照が起こらなくなる 15
  8. なぜ var h: Hoge? = Hoge() // Hoge の参照カウント1 ,

    closure の参照カウント1 h = nil // Hoge の参照カウント0 16
  9. まとめ { [weak self] event in guard let strongSelf =

    self else { return } // なんかする } [weak self] と書くことでクロージャが self を弱参照し、クロージャと self の循環参照を 防ぐ 18
  10. 19