読者です 読者をやめる 読者になる 読者になる

#iosdc 2016 A-6 メモリー管理の嬉しいバイキング料理

twitter.com

Swiftの初心者の中には、自動参照カウントを使えば、メモリー管理は気にしなくても良いと認識している方が多くいます。確かにSwiftは、ごみ収集システムを使うより、予測可能性は高いと言えます。しかし自動参照カウントを使用する際は、メモリー構造を意識する必要があります。ユーザーは、幾つかの方法でメモリー構造の落とし穴を避けることができます。今回のトークでは、メモリーの取り扱い方法について分かりやく説明します。

iosdc.jp

speakerdeck.com

モリー管理の嬉しいバイキング料理

f:id:niwatako:20160820135650j:plain

f:id:niwatako:20160820135652j:plain

f:id:niwatako:20160820135653j:plain

iPadで操作する顕微鏡を開発しています。

f:id:niwatako:20160820135709j:plain

Swiftは自動でメモリを管理してくれます。

なので心配しなくていいという人がいるかもしれませんが、少し仕組みがわかると精度が高い、バグのないプログラムを書ける。

メモリの割り付けはこのどちらか

f:id:niwatako:20160820135741j:plain 

f:id:niwatako:20160820135759j:plain

スコープから出ると全部開放される。とても早い処理です。

f:id:niwatako:20160820135811j:plain

f:id:niwatako:20160820135825j:plain

ただ、スコープから出るときに必ず開放する、もう少しダイナミックにしたい時がある。

その時はヒープ領域を参照型で使う

f:id:niwatako:20160820135850j:plain

ヒープをロックして

f:id:niwatako:20160820135911j:plain

スタックから一つ参照される

f:id:niwatako:20160820135934j:plain

f:id:niwatako:20160820135955j:plain

f:id:niwatako:20160820140014j:plain

f:id:niwatako:20160820140018j:plain

f:id:niwatako:20160820140026j:plain

変数の名前を定数にすれば代入しようとするとRejectされる。参照型では定数を使ったほうが良い。

す宅からの参照が消えればリリースされるが問題が起きることもある。

f:id:niwatako:20160820140100j:plain

循環参照の例

f:id:niwatako:20160820140131j:plain

f:id:niwatako:20160820140138j:plain

f:id:niwatako:20160820140156j:plain

Xcodeではグラフが出るようになりましたね

f:id:niwatako:20160820140209j:plain

治すには弱参照を使います

f:id:niwatako:20160820140234j:plain

f:id:niwatako:20160820140252j:plain

このように参照が全部言えると弱い参照に対して勝手にnilになる。

f:id:niwatako:20160820140300j:plain

f:id:niwatako:20160820140327j:plain

Objective-Cはロッキングテーブルを使っていた

Swiftではゾンビが残って、消えているはずの参照を見に来たらnilを返して、本当に参照が無くなった時開放される。

f:id:niwatako:20160820140409j:plain

お前はもう死んでいる

f:id:niwatako:20160820140428j:plain

もうひとつUnownedがあるが、これは参照がかならずあることを前提にしていてなければプログラムが停止する。

f:id:niwatako:20160820140453j:plain

f:id:niwatako:20160820140348j:plain

動きは先程と同じ、ゾンビを見に行ったら、nilを返すのではなくて、これはダメだとプログラムを停止する。

f:id:niwatako:20160820140521j:plain

f:id:niwatako:20160820140552j:plain

f:id:niwatako:20160820140602j:plain

f:id:niwatako:20160820140614j:plain

これはコンパイルできない。

self. を書きなさいと言われる。それが循環参照を作っているかもしれないというヒント。

f:id:niwatako:20160820140647j:plain

f:id:niwatako:20160820140655j:plain

f:id:niwatako:20160820140718j:plain

f:id:niwatako:20160820140730j:plain

このパターン覚えました?非同期のケースを考えましょう

f:id:niwatako:20160820140744j:plain

f:id:niwatako:20160820140809j:plain

Why Swift Peaple, Why...

f:id:niwatako:20160820140831j:plain

強参照で参照し続ける必要がある。

延命したくない時は

f:id:niwatako:20160820140902j:plain

一般的にはチェックを行う

f:id:niwatako:20160820140915j:plain

まとめ

f:id:niwatako:20160820140944j:plain

たとえば次のSwift5,6辺りでよくなって、わかりやすくなるのではと思うけど、非同期はなんとかなるかもしれないですね。でも原理としてはなくならないと思います。予測性があってAppleは多分私の考えでは設計ツールやビジャライズのツールが良くなってきて、プログラマとして設計の時に考えるようになるのではないかと思います。

f:id:niwatako:20160820141050j:plain

f:id:niwatako:20160820141054j:plain

Q&A

weak self を書かなくても循環参照になっていないのはなぜか

クロージャの参照を持っているのが self ではないので循環参照にならない

strong weak 踊りは英語では?

strong weak dance

日本語でもダンスのほうが良いと思います

(会場笑い)

ゾンビの辺りで、聴き逃しかも知れないが、ゾンビの発生条件をお聞きしてもよろしいですか

strong の参照カウントが0になるとdeinitializeが走る。weakカウントが0ならメモリを開放するが、そうでなければメモリは残る。weakカウントが下がる、あるいはアクセスをすると下がる、そのweakカウントが0になった時にメモリまでカウントする。

weak用の参照カウントがあるということですね。weakの参照でメモリリークすることがあるのでしょうか

シエスタというネットワークライブラリがあってキャッシュ機能があるが、strongをweakに変えている箇所があるがそれだけでは開放されない。 参考文献に詳しく書かれているのでそちらの参照を是非

感想

twitter.com

twitter.com

twitter.com

twitter.com

twitter.com

twitter.com

twitter.com

twitter.com

twitter.com

twitter.com

まとめ