最終更新:
bokkuri_orz 2014年09月22日(月) 01:18:21履歴
Cocoa環境のObjective-Cで用意されているメモリ管理方式。
- リファレンスカウンタ
- ARC(Automatic Reference Counting)
- ガーベジコレクション (Objective-C 2.0 移行。iOSでは使えない)
(1)オブジェクトA が alloc + init でインスタンス生成(リファレンスカウンタ=1)
オブジェクトA → (インスタンス) オブジェクトB
(2)オブジェクトBがインスタンスを参照する(リファレンスカウンタ=1)
オブジェクトA → (インスタンス) ← オブジェクトB
(3)オブジェクト1がインスタンスの参照をやめる(リファレンスカウンタ=0)
オブジェクトA (インスタンス) ← オブジェクトB
(4)インスタンスが開放されるが、オブジェクトBはインスタンスが存在していたメモリを参照したまま。
オブジェクトA ( ) ← オブジェクトB
(1)オブジェクトA が alloc + init でインスタンス生成(リファレンスカウンタ=1)
オブジェクトA → (インスタンス) オブジェクトB
(2)オブジェクトBがインスタンスを参照し、retainを呼ぶ(リファレンスカウンタ=2)
オブジェクトA → (インスタンス) ← オブジェクトB
(3)オブジェクト1がインスタンスの参照をやめる(リファレンスカウンタ=1)
オブジェクトA (インスタンス) ← オブジェクトB
(4)インスタンスのリファレンスカウンタが残っているので、インスタンスは破棄されずに残っている(ルファレンスカウンタ=1)
オブジェクトA (インスタンス) ← オブジェクトB
オブジェクトがインスタンスをalloc+initしたり、retainを送ってカウンタをインクリメントすることで、
そのインスタンスを保持(retain)していることになる。
インスタンスを保持することを、 「オーナーシップを持っている」 という。
// NSObjectを継承する
@interface MyObj: NSObject
{
}
// イニシャライザ -(id)new という書き方もある
-(id)init;
-(void)dealloc;
@end
@implementation MyObj
-(id)init
{
printf("MyObj init\n");
return self;
}
-(void)dealloc
{
printf("MyObj dealloc\n");
[super dealloc];
}
@end
{
MyObj* obj = [[MyObj alloc] init];
printf("retainCount 0 : %d\n", (int)[obj retainCount]);
[obj retain];
printf("retainCount 1 : %d\n", (int)[obj retainCount]);
[obj release];
printf("retainCount 2 : %d\n", (int)[obj retainCount]);
[obj release];
}
●実行結果
MyObj init retainCount 0 : 1 retainCount 1 : 2 retainCount 2 : 1 MyObj dealloc
オーナーシップを持つ場合の注意点について。
-(void)setMyValue:(id)obj
{
[myValue release];
myValue = [obj retain]; // ← myValue同じインスタンスが渡された場合、上のreleaseで解放されてしまうことがある。
}
●対策
//例1
-(void)setMyValue:(id)obj
{
[obj retain]; // リファレンスカウンタを先に増やしておく
[myValue release]; // 上記対応で、ここで解放されることがなくなる
myValue = obj;
}
//例2
-(void)setMyValue:(id)obj
{
if(myValue != obj)
{
[myValue release];
myValue = [obj retain];
}
}
NSAutoreleasePool を使うと、後でまとめてインスタンスへreleaseメッセージを送ることが出来る。
前述の MyObj を使った例。
●サンプルコード
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // 自動解放プール開始
MyObj* obj = [[MyObj alloc] init];
[obj autorelease]; // 自動解放プールへ登録
[pool drain]; // 自動解放プール終了
}
●実行結果
MyObj init MyObj dealloc
NSString のメソッド
| メソッド | 説明 | 所有者 |
| -(id) initWithUTF8String | allocで生成したインスタンスに対するイニシャライザ。 | 生成したオブジェクトがインスタンスのオーナー |
| +(id) stringWithUTF8String | 一時的なインスタンスを生成するメソッド | オーナー無し。自動解放プールに登録される。 |
●メソッドの命名規則
allocのイニシャライザは init〜
一時的なインスタンスを生成するメソッド、文字列は string〜、配列は array〜 という感じ。
タグ


最新コメント