【iPhoneアプリ】インスタンスとメモリー管理について
本当は、プロパティ「@proerty」の使い方を書くつもりでしたが...
まず最初に「インスタンス」の仕組みを書かないと、書いてる本人が
わからなくなりそうだったので、この題目にしました。
今回は、「インスタンスとメモリー管理」についてです。
まず、プログラム上で使われるメモリーの種類について
細かいと事を省いて、論理的に4種類あります。
▼プログラム領域
プログラムコードが格納されている。
▼静的領域
グローバル変数、static変数が格納されている。
▼スタック領域
自動変数、メソッドの引数、メソッドの戻り番地が格納されている。
▼ヒープ領域(利用出来るサイズが大きい)
インスタンス(alloc)を行ったインスタンス変数が格納されている。
この中で今回、お話しするのが
「スタック領域」「ヒープ領域」になります。
では、クラスを作成し、インスタンスを行うまでの過程で、どのようにメモリーが
使われるのかを記載したいと思います。
▼まず、以下のコードでクラスを作成します。
ヘッダーファイルの変数宣言はこのような感じにします。
LaboObject.h
@interface LaboObject : NSObject @private NSString *labo1; @private NSString *labo2; @public NSString *laboA; @public NSString *laboB; @end
次に、モデルファイルのメソッド実装はこのような感じにします。
LaboObject.m
@implementation LaboObject +(NSString*)laboMethod1{ NSString *labo1 = @"labo1"; return labo1; } +(NSString*)laboMethod2{ NSString *labo2 = @"labo2"; return labo2; } -(NSString*)laboMethodA{ return laboA; } -(NSString*)laboMethodB{ return laboB; } @end
このプログラムをイメージで表すと下記の感じになります。
注意 変数名とメソッド名は違います
▼次に、このクラスをインスタンスすると
メモリーはどのように格納されるのかを説明します。
以下のコードでインスタンスします。
//インスタンス LaboObject *Class = [[LaboObject alloc] init];
インスタンスを実行すると以下の図のように「ヒープ領域」に変数が格納されます。
また、次のように2回インスタンスを実行してみます。
//インスタンス 1個目 LaboObject *Class1 = [[LaboObject alloc] init]; //インスタンス 2個目 LaboObject *Class2 = [[LaboObject alloc] init];
そうすると、メモリーの格納状況は以下のようにオブジェクト毎に格納されます。
後半は「メソッド」のメモリー格納状況などを記載します。
余談ですが、変数を宣言する時に「*」を付けますが
これは何を意味しているのかというと、メモリーのアドレスを指してます。
これにより、同オブジェクトの変数と認識しているそうです。
こんな感じですかね。
▼次に「メソッド」部分はどこに格納されるんですか
というと「スタック領域」になります。
ちなみに、メソッドの場合は初回にインスタンスされるとそれ以降、
何回もインスタンスされても、メモリーには格納される事はありません。
イメージとしては、このような感じです。
▼今ままでの説明内容をまとめると
インスタンス後のオブジェクトは以下のイメージ図のようになります。
▼また、インスタンス後の変数参照やメソッド参照はこんなイメージになります。
ちなみに、インスタンス後の変数には値ではなく、値が格納されたメモリーのアドレスが代入されます。
▼変数参照のイメージ
▼メソッド参照のイメージ