#メモリ管理って一体なんのことだ
Objective-Cをやっています。メモリ管理とは一体何のことでしょうか……
勉強しながら、まとめてみます。
以前にRubyのクラスとインスタンスで書きましたが、インスタンスってそもそも何なのでしょうか?
あれは配列やDBに格納する処理を特にしなかった場合、いつのまにかどこかに行っています。
使い終わった後、いったい何が起きているんでしょうか? railsをやっていた頃はさっぱり分かりませんでした。
#インスタンスはメモリに保存されているらしい
インスタンスはメモリに保存されています。macbookだと8GBぐらいあるアレですね。
8GBあるといっても最近のプログラムは複雑化していますし、マルチタスクでいろんなプログラムを実行しているわけですから、あくまでも8GBという限られた領域しかありません。
もし使用済みのインスタンスがメモリ上に残っていた場合、メモリを圧迫することになります。これをメモリリークと呼ぶそうです。
ですからメモリをその都度、解放する必要があるんですね。
Objective-CではARC(Automatic Reference Counting)という機能があり、これがメモリ管理をある程度やってくれています。
#保持カウンタ
各インスタンスには保持カウンタという数値があり、生成したときには「1」が設定されています。
これはNSObjectクラスのretainCountというプロパティを参照することで、確認できます。
試しに昨日書いたDogクラスの練習コードにぶちこんでみます。
###コード
#import <Foundation/Foundation.h>
@interface Dog : NSObject
{
@private
int height;
int weight;
}
@property int height, weight;
@end
@implementation Dog
@synthesize height, weight;
+(void)nakigoe
{
NSLog(@"犬の鳴き声は一般的に「ワンワンです」");
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
Dog *dog_A = [[Dog alloc] init];
NSLog(@"値は「%ld」ですね!", [dog_A retainCount]);
[dog_A setHeight:100];
[dog_A setWeight:500];
NSLog(@"犬Aの高さは地面から%d、体重は%dです。",
[dog_A height], [dog_A weight]);
[Dog nakigoe];
}
return 0;
}
###実行結果
2017-09-22 19:47:49.398696+0900 Objective-C--2[66271:22500460] 値は「1」ですね!
2017-09-22 19:47:49.400036+0900 Objective-C--2[66271:22500460] 犬Aの高さは地面から100、体重は500です。
2017-09-22 19:47:49.400072+0900 Objective-C--2[66271:22500460] 犬の鳴き声は一般的に「ワンワンです」
Program ended with exit code: 0
確かに「1」が返ってきてますね!
#保持カウンタの増減
ARCをオフに設定している時には、以下のような操作でインスタンスを解放するそうです。
NSObjectのメソッドを使います。
retainメソッド +1
releaseメソッド -1
この操作によって保持カウンタが「0」になった時、インスタンス(メモリ)が解放されるということですね!
次の処理に必要なインスタンスを解放してしまうようなことがあっても、コンパイル自体は通ってしまいますが、プログラムがエラーしてしまいます。
メモリ管理は正確に行わなければなりません。
#autoreleasepool
Objective-Cではプログラムを@autoreleasepool{}
のブロック内に書くことになっていますが、実はこれはブロックの終了時に各インスタンスにrelease
命令を送っているんですね。
@autoreleasepool
は必要に応じてネストさせて記述することもできます。
#以上です!
ざっくりですが、とりあえずインスタンスのことが前よりわかった気がします!
もうちょっと奥がいろいろありますので、今後またまとめたいと思います!
ありがとうございました!