post Image
Xcode8のDebug Memory GraphでCFArrayのメモリリークの原因を探る

MAMORIO株式会社でiOSエンジニアをしている佐藤です。
今WWDC開催中のサンノゼで書いてます。
WWDCのラボでメモリリークの知見が得られたので共有します。

環境

  • Xcode8.3.3
  • Swift3.1
  • iOS10.3.2

問題

Xcode8からDebug Memory Graphの機能が追加され、ランタイム上でのインスタンスのメモリーが表示出来るようになりました。
プロジェクトのコードでリークしていたのをポチポチ潰していたのですが、どうしてもわからない表示がありました。

20170607_1496823193.jpg

CFArrayのインスタンスのメモリリークです。
Arrayがリークしていると言われてもどうすればいいかがわかりません。

Arrayの定義はFoundationだからFoundationのバグ?
いやそんなはずあるのか?
とは言え自分のコードのどこが悪いのかがわからないのでどうすればいいかがわからない。。

とモヤモヤしてたのですが、Appleのラボで聞いてきたところある設定をすればいいとのことでした

DiagnosticsのLogging Malloc Stack

ターゲットのスキームをEdit Schemeで編集します。

Run > Diagnostics > Logging のMalloc StackにチェックをいれてLive Allocations Onlyを選択します。
 2017-06-06 15.08.08.jpg

これで生きているインスタンを表示できるようになります。
試しにビルドしてDebug Memory Graphを起動してみると

20170607_1496825206.jpg

出てきました。Backtraceの項目にシステムではない、自分で実装したメソッドが表示されました。
ここがおかしいからこのインスタンスがメモリリークしているのでしょう。

原因を特定できました。

おわりに

メソッドをみると循環参照になっているようです。
原因がわかれば対応ができます。
これを発見できたことでもWWDCに参加してよかったと思います。
みなさんも参考にしてください。


『 Swift 』Article List