ARCでメモリリークを起こさないようにするために
先月objective-cなるプログラミングを始めた自分にとって
objective-cはARCを使っていますというのは
そういうものなんだふーん。
って感じだったんですが
思っていた以上にこれは重要なことのようです。
よくよく調べてみるとARCかどうかに関係なくメモリ管理については注意が必要なようです。
特にメモリを沢山使うゲームのようなアプリでcocos2dを使わないでメモリ管理をする今回のようなケースにおいては特に重要だと思っています。
例えば「autoreleaseされたインスタンス」です。
実際にはautoreleaseというキーワードはソースコードの中で使いませんが、
一般にオブジェクトをインスタンス化した瞬間にautoreleaseされたオブジェクトと認識されるようです。
具体的には以下のようなケースです。
for (int i = 0; i < 100; i++) { NSData* data = [NSData dataWithContentsOfFile:@"..."]; }
このようにループの中で新しいインスタンスを生成すると
ループ(スコープ?)の外に制御が移っても
このインスタンスのメモリが解放されずに残ってしまうらしいのです。
(制御が移るっていう言い方が正しいのか分かりませんが)
http://qiita.com/amay077/items/95a4139e6f553d8a56a1
この場合、以下のように@autoreleasepool{}でくくってやれば解放されます。
for (int i = 0; i < 100; i++) { @autoreleasepool { NSData* data = [NSData dataWithContentsOfFile:@"..."]; [NSThread sleepForTimeInterval:0.5]; } }
あとは個人的にハマったのは
importされているクラス側でimportしてしまう等の「循環参照」の問題です。
これについては次回書きます。
他にも
・[UIImage imageNamed:@"..."]を使用しない(イメージデータが保存されたまま解放されない)
等の注意点もあるようです。
もしARCでなかったら手動でメモリを管理しなければならないので
ARCの導入によって一見便利になった一方で、
こうしたメモリ管理も十分に気をつけて開発しなければいけませんね。
続きます。