Xcode
iOS
ARC
メモリ管理

iOSアプリ開発:エラー対策(Received memory warning.)

More than 3 years have passed since last update.

現象

色々と画像や音をプロジェクトに追加して、
端末で動作確認をしていたら突然下記文字列がコンソールウィンドウに表示されました。

Received memory warning.

この文字列が表示された時は特に問題ありませんが、
しばらく動作確認を続けているとアプリが勝手に終了してしまいました。

コンソールウィンドウ

コンソールウィンドウは、Xcode上の下に表示されます。
もし表示されていない場合、下記手順で表示出来ます。

Xcode->View->Debug Area->Active Console

コンソールウィンドウは、
Xcodeからのシステム的なメッセージか下記APIプログラムを使用すると表示されます。

  • NSLog
  • print

調査

色々調べてみると、メモリ不足警告のようです。
基本、自身で確保したもの(malloc等)は不要となったら解放(free等)しましょう。

ARC(Automatic Reference Counting)で、メモリ管理を自動で行っている場合、自動解放してくれるだろうと思っていても解放しないものもあるようで注意しましょう。

自分が実際に既に対応したもの
* CGContextRef→CGContextReleaseを使って解放

対応

実際に自分が発生した処理を下記に記述しておきます。
対応は、コメントで追加start、追加endと記述した間です。

Test.h
void* Test();
Test.c
void* Test()
{
    void* test = NULL;
    test = malloc(10);
    return test;
}
TestMain.h
#import "Test.h"

@interface TestMain : NSObject
{
    void* data;
}
@end
TestMain.m
#import "TestMain.h"

@implementation TestMain
- (void)Test2
{
    // 追加 start
    if (data != NULL) {
        free(data);
    }
    // 追加 end

    data = Test();
}
@end

本来、Test関数でmallocしているためその中でfreeしてあげるのがベストだと思います。
しかし、今回はこれをreturnさせたかったため、freeしなかったらTest2が呼ばれるたびメモリを確保していってメモリ不足となってしまったようです。

Test2関数で呼んだ後、メモリを参照したいため呼んだ後もfree出来ません。
なので、Test2を呼ぶ前にfreeする必要があるかチェックするようにしました。

これにより、文字列(Received memory warning.)は出なくなり、
アプリも勝手に終了しなくなりました。

色々実装していったらまた発生しそうなので、気を付けたいと思います。