アクセサメソッド – 2

前々回のエントリでアクセサメソッドについて書きましたが、後からひとつだけ気になったことがあります。

最も推奨されるアクセサメソッドのgetterの方は、次のようなコードでした。(Cocoa基礎ガイド>Cocoaプログラムへの動作の追加 – アクセサメソッドから引用)

- (NSString *)title {
    return [[title retain] autorelease];
 }

前に説明した通り、getしている途中,またはgetしたオブジェクトを操作中に、オブジェクトが破棄されるのを防ぐために、このような書き方をしています。

ここでひとつ思いついたのですが、deallocメソッドでオブジェクトを破棄するときも、releaseではなくautoreleaseを使用することにより、getterをあのように書かかなくていいのではないか、ということです。要するにこういうことです。

- (NSString *)title {
    return title; //そのまま
 }
- (void)dealloc
{
    [title autorelease]; //releaseを使わない
    [super dealloc];
}

ただ、この方法をすると、オブジェクトを破棄したタイミングで、すぐにオブジェクトが破棄されるとは限りません。Cocoaではdeallocをきっかけに動かすようなコードを使うことがありませんが(むしろ非推奨)、例えばインスタンス変数のインスタンスがautoreleaseされて解放されたときに、インスタンス変数のdeallocが呼ばれる訳ですが、そのdeallocの中でも、さらにautoreleaseを使ってオブジェクトを破棄しているとすると、autoreleasepoolが何度かreleaseされないと、すべてのオブジェクトがreleaseされないことになります。

これが問題になるかといえば、特に問題にはならないとは思うのですが、気分的にはAppleの公式の推奨コードのが良い気がします。ただ、コード的にはretainしてautoreleaseしているのが奇妙なので、どちらかといえば後者の書き方のが自然かもしれません。

と、いろいろアクセサメソッドについて書いていますが、適当なアプリケーションを作る場合は、こんなので十分だったりします。

- (NSString *)title {
    return title;
 }
 - (void)setTitle:(NSString *)newTitle {
        [title release];
        title = [newTitle copy];
    }
 }
- (void)dealloc
{
   [title release];
}

使い分けは感覚に任せてしまうことが多いですが、やはりきちんとしたアプリケーションや、そこそこ大きなアプリケーションを書く場合は、どこでバグが起こるか分からないので、こういうことからひとつずつ可能性をつぶして行くべきだと思います。

コメント投稿