ゆるい感じのプログラムを書きたい。

プログラムの敷居を下げて、多くの人が開発出来るように色々書いていきます!

【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


このプログラムをイメージで表すと下記の感じになります。
注意 変数名とメソッド名は違います

f:id:kassans:20140226190648p:plain

▼次に、このクラスをインスタンスすると
メモリーはどのように格納されるのかを説明します。


以下のコードでインスタンスします。

//インスタンス
LaboObject *Class = [[LaboObject alloc] init];


インスタンスを実行すると以下の図のように「ヒープ領域」に変数が格納されます。

f:id:kassans:20140226203501p:plain


また、次のように2回インスタンスを実行してみます。

//インスタンス 1個目
LaboObject *Class1 = [[LaboObject alloc] init];
//インスタンス 2個目
LaboObject *Class2 = [[LaboObject alloc] init];


そうすると、メモリーの格納状況は以下のようにオブジェクト毎に格納されます。

f:id:kassans:20140226192356p:plain


後半は「メソッド」のメモリー格納状況などを記載します。



余談ですが、変数を宣言する時に「*」を付けますが
これは何を意味しているのかというと、メモリーのアドレスを指してます。

これにより、同オブジェクトの変数と認識しているそうです。
こんな感じですかね。

f:id:kassans:20140226193649p:plain

▼次に「メソッド」部分はどこに格納されるんですか
というと「スタック領域」になります。

ちなみに、メソッドの場合は初回にインスタンスされるとそれ以降、
何回もインスタンスされても、メモリーには格納される事はありません。


イメージとしては、このような感じです。
f:id:kassans:20140226194646p:plain


▼今ままでの説明内容をまとめると
インスタンス後のオブジェクトは以下のイメージ図のようになります。

f:id:kassans:20140226194810p:plain


▼また、インスタンス後の変数参照メソッド参照はこんなイメージになります。

ちなみに、インスタンス後の変数には値ではなく、値が格納されたメモリーのアドレスが代入されます。


▼変数参照のイメージ

f:id:kassans:20140226195244p:plain


▼メソッド参照のイメージ

f:id:kassans:20140226195248p:plain