Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Swiftでなんで[weak self]するのか?
Search
oyuk
April 05, 2018
2
4.6k
Swiftでなんで[weak self]するのか?
oyuk
April 05, 2018
Tweet
Share
More Decks by oyuk
See All by oyuk
Shorebird について
oyuk
0
330
Material designのWindow size classについて
oyuk
0
930
LLVMについて調べた
oyuk
0
170
Swiftのmapからその次へ
oyuk
1
1.3k
Featured
See All Featured
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
7.5k
Designing Experiences People Love
moore
138
23k
Designing for Performance
lara
604
68k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
25
660
The Language of Interfaces
destraynor
154
24k
How GitHub (no longer) Works
holman
311
140k
Building a Scalable Design System with Sketch
lauravandoore
459
32k
10 Git Anti Patterns You Should be Aware of
lemiorhan
653
59k
Bootstrapping a Software Product
garrettdimon
PRO
304
110k
Art, The Web, and Tiny UX
lynnandtonic
296
20k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
7
580
Web development in the modern age
philhawksworth
205
10k
Transcript
Swiftでなんで[weak self]するのか? 2018/03/30 oyuk(@oydku) 1
自己紹介 oyuk(@oydku) プログラマ 2
weak selfについて よくあるアレ { [weak self] event in guard let
strongSelf = self else { return } // なんかする } 3
結論から [weak self] と書くことでクロージャが self を弱参照し、クロージャと self の循環参照を防ぐ 4
は? [weak self] ってなんじゃその書き方は 弱参照?循環参照? 5
[weak self] ってそんな書き方ありなん? 今回の本質じゃないから軽く 「 [weak self] と書くことでクロージャが self を弱参照する」これだけ覚えておいて
ちなみに [weak self] はキャプチャリストと呼ぶ 6
弱参照?循環参照? 参照カウントというGCの概念 これを理解するために 参照カウントについて Swiftの参照カウント(Automatic Reference Counting)について少し 7
参照カウント GCの一種 オブジェクトに対して参照している他のオブジェクトの数を記憶する(参照カウント) 1以上なら生きている。メモリに割り当てられている 0になると死。解放される 8
参照カウント 例1 class Hoge {} // Hoge のインスタンスの参照カウントが1 になる var
h: Hoge? = Hoge() 9
参照カウント 例2 class Hoge {} // Hoge のインスタンスの参照カウントが1 になる var
h: Hoge? = Hoge() // Hoge のインスタンスの参照カウントが0 になり解放される h = nil 10
参照カウント 例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 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
循環参照 var h: Hoge? = Hoge() // Hoge の参照カウント2 ,
closure の参照カウント1 h = nil // Hoge の参照カウント1 13
循環参照解決策 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
なぜ func createClosure() -> (()-> Void) { return { [weak
self] in self?.count += 1 } } [weak self] は self を参照するが参照カウントは+1しないという意味 これが弱参照 ちなみに今までのは強参照 循環参照が起こらなくなる 15
なぜ var h: Hoge? = Hoge() // Hoge の参照カウント1 ,
closure の参照カウント1 h = nil // Hoge の参照カウント0 16
なぜ hは参照カウントは0なので解放される closureも参照カウント0なので解放される 17
まとめ { [weak self] event in guard let strongSelf =
self else { return } // なんかする } [weak self] と書くことでクロージャが self を弱参照し、クロージャと self の循環参照を 防ぐ 18
19