Objective-C 2.0ではガベージコレクションが導入されて、メモリ管理がだいぶシンプルになりましたが、iPhone開発ではその恩恵に預かれませんので、色々と気を使います。
NSArrayに要素を追加した時、NSArrayはその要素オブジェクトにretainメッセージを送ってオーナーシップを獲得します。NSArrayが解放された場合、格納されているオブジェクトすべてにreleaseメッセージが送られます。また、格納した要素をNSArrayから削除した場合、その要素にreleaseメッセージが送られます。
なので、こういう書き方をするのはちょいとよろしくありません。
NSArray *array = [[NSArray alloc] initWithObjects:
[[Foo alloc] init], [[Bar alloc] init],nil];
// なんらかの処理
[array release];
FooとBarをallocしてinitした時点で、このコードが書かれているオブジェクトがFooとBarそれぞれのオーナーになります。その後、array に追加しているので、array もこの2つの要素のオーナーシップを持ちます。
array を release する事で、Foo と Bar にもreleaseメッセージが送信され、retainCount が減るのですが、コードが書かれてるオブジェクトがまだオーナーシップを握っているため、破棄されません。このコードだと破棄しようもない。困った。
なので、律儀にこう書くのが吉。
Foo *foo = [[Foo alloc] init]; Bar *bar = [[Bar alloc] init]; NSArray *array = [[NSArray alloc] initWithObjects: foo, bar, nil]; [foo release]; [bar release]; // なんらかの処理 [array release];
これじゃどんくさい、という人はautoreleaseにまかせてしまうとか。
NSArray *array = [[NSArray alloc] initWithObjects:
[[[Foo alloc] init]autorelease], [[[Bar alloc] init]autorelease], nil];
// なんらかの処理
[array release];
iPhone環境はautoreleaseは結構まめにやってくれる事がこないだ判ったので、これで安心でしょう。
NSDictionaryの場合、こちらもNSArrayとほぼ同様なのですが、値はそのまま参照してretainメッセージを送りますが、キーはオブジェクトをコピーして保持するそうです。
私はどんくさい方が好みです。実生活ではぐうたらであまり掃除は得意でないんですが。



0 コメント:
コメントを投稿