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
5.1k
Swiftでなんで[weak self]するのか?
oyuk
April 05, 2018
Tweet
Share
More Decks by oyuk
See All by oyuk
Shorebird について
oyuk
0
440
Material designのWindow size classについて
oyuk
0
1.3k
LLVMについて調べた
oyuk
0
190
Swiftのmapからその次へ
oyuk
1
1.3k
Featured
See All Featured
Visualization
eitanlees
150
16k
Navigating Team Friction
lara
190
15k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
1.7k
Building Adaptive Systems
keathley
44
2.8k
BBQ
matthewcrist
89
9.9k
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
658
61k
GitHub's CSS Performance
jonrohan
1032
470k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.7k
Six Lessons from altMBA
skipperchong
29
4k
Making Projects Easy
brettharned
120
6.4k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.3k
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