objective-cでretainCountが増えるとき減るときの確認
Objective-cでiPhoneやiPadのアプリ開発をしているが、GCのない言語をまともに使ったことがないので混乱している。
頭を整理するためにViewBasedApplicationを使って試してみる。
基本
- (void)viewDidLoad { [super viewDidLoad]; UIView *a = [[UIView alloc] init]; LOG(@"a retainCount:%d",[a retainCount]); // => 1 [self.view addSubview:a]; LOG(@"a retainCount:%d",[a retainCount]); // => 2 増えた [a removeFromSuperview]; LOG(@"a retainCount:%d",[a retainCount]); // => 1 }
- allocしたときに増える
- addSubviewしたとき増える
- removeFromSuperviewしたときに減る
addSubviewで増えたcountはいつ減るのか
さらにaにsubview bが、bにsubview cがついたとき
- UIView a
- UIview b
- UIView c
- UIview b
- (void)viewDidLoad { [super viewDidLoad]; UIView *a = [[UIView alloc] init]; [self.view addSubview:a]; LOG(@"a retainCount:%d",[a retainCount]); // => 2 UIView *b = [[[UIView alloc] init] autorelease]; UIView *c = [[[UIView alloc] init] autorelease]; [a addSubview:b]; [b addSubview:c]; LOG(@"a retainCount:%d",[a retainCount]); // => 2 LOG(@"b retainCount:%d",[b retainCount]); // => 2 LOG(@"c retainCount:%d",[c retainCount]); // => 2 [a removeFromSuperview]; LOG(@"a retainCount:%d",[a retainCount]); // => 1 (減った) LOG(@"b retainCount:%d",[b retainCount]); // => 2 (ここでは減らない) LOG(@"c retainCount:%d",[c retainCount]); // => 2 [a release]; LOG(@"b retainCount:%d",[b retainCount]); // => 1 (減った) LOG(@"c retainCount:%d",[c retainCount]); // => 2 (ここでは減らない) }
- aにsubviewがついてもaのcountは増えない(増えるように見える時があるのはなんだろ)
- bはaがリリースされるとretainCountが減る([a removeFromSuperview]のタイミングではない)
- cはbのdeallocが呼ばれないのでreleaseされないのだろう
MutableArrayやMutableDictionaryで増えたcountはいつ減るのか
- (void)viewDidLoad { [super viewDidLoad]; NSMutableArray *d = [NSMutableArray array]; NSObject *obj1 = [[NSObject alloc]init]; LOG(@"d retainCount:%d",[d retainCount]); // => 1 LOG(@"obj1 retainCount:%d",[obj1 retainCount]); // => 2 [d addObject:obj1]; LOG(@"d retainCount:%d",[d retainCount]); // => 1 LOG(@"obj1 retainCount:%d",[obj1 retainCount]); // => 2 [d release]; LOG(@"obj1 retainCount:%d",[obj1 retainCount]); // => 1 }
- addObjectするとobj1は増える
- MutableArrayを削除すればobj1は減る
autorelease
retainCountが1になったら殺すという死刑宣告。retainしてやれば延命できる。
あとは
Objective-C プログラミング言語:メモリ管理を熟読するのが早い
結論
- alloc, copy(なんちゃらcopy, copyなんちゃらを含む) , retain, addSubview, addObject(その他addなんちゃら)をすると増える
- addなんちゃらで増えたcountはaddしたオブジェクトが解放されれば減る
疑問
autoreleaseプールの仕組み。例えば
NSObject *a; for(int i=0; i<100; i++){ a = [[[NSObject alloc] init] autorelease]; }
は全部リリースされるのかどうか不安