@synthesizeはselfでアクセッサが機能する

2011/02/23

Objective-Cを勉強し始めた頃、Objective-C 基礎編 Vol2で、@synthesizeについてメモをした。

この時は実践してなかったので、チンプンカンプン。 で、数ヶ月経った今、本当に基本的な機能を知らなかった事が判明・・・。

@synthesize で定義したプロパティはselfでないとアクセッサが機能しない!

ちょっと脱力です(^^;)

今まではselfなしで・・・

今までは、プロパティには self をつけずにコーディングしてました。 で、deallocの処理で律儀に全部 release していたのです。

@synthesizeで定義されたプロパティは以下のsetter、getterを処理してくれます。

- (id) foo {
    return foo;
}
- (void) setFoo:(id) aFoo {
    if (aFoo != foo) {
        [aFoo retain];
        [foo release];
        foo = aFoo;
    }
}

よって、dealloc() で release する必要がなく nil にするだけです。

@property (nonatomic, retain) Person person;

@synthesize person;

- (void)viewDidLoad {
    [super viewDidLoad];
    self.person = [[Person alloc] init];
}

- (void)walk {
    self.person = ....
}

- (void)dealloc {
    person = nil;
}

[[Person alloc] init] しないケース(他の画面遷移からオブジェクトを受ける等)場合は、 deallocのperson = nil さえ要らないケースもあるかも知れませんが、とりあえず nilにしておいた方が安全ですかね?

@synthesize は selfを絶対に利用すべき?

はっきり言って、自分はわかりません(賢い人教えてw)。 selfを利用するかどうかは人それぞれかも知れませんし、 現に自分もdealloc→releaseで取りあえず何とかなっていたみたいなので。

ただ、releaseを書くくらいなら、selfでアクセスする癖を付けた方が良いのかなぁ?とも思いました。 あとNSIntegerとかポインターでないオブジェクトは別に関係ないかも知れません。

2011/10/17 追記

カスタムクラスのインスタンスの扱いでも記載したように、init する場合は明示的に

Person _person = [[Person alloc] init];
self.person = _person;
[_person release];

とrelease した方がAnalyze で警告を防げます。 また、以下のコードでも問題はないかも。

person = [[Person alloc] init];

ただし init 以降の person のアクセスは、self.person で行うべきです。