@property(nonatomic, retain)をしたときのメモリ管理の動き

はじめに

@property(nonatomic, retain) したときのメモリ管理の動きが気になりここに示す。

前提:@property(nonatomic, retain) のセッターの擬似ソース

-(void) setName:(TYPE)obj{
  if(name != obj ){
    [name release];
    name = [obj retain];
  }
}
参考

詳解 Objective-C 2.0 第3版

詳解 Objective-C 2.0 第3版


つまり、retainを設定した場合は、
何か別のインスタンスを代入したとき、すでに参照しているインスタンスをrelease(参照カウントを-1)している。

arrでアクセスした場合

ヘッダー.h
@property(nonatomic, retain) NSArray *arr;
実装.m
@synthesize arr;

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"arr : %@", arr);  //=> null
    arr = [[NSArray alloc] init];
    NSLog(@"arr retainCount : %d", [self.arr retainCount]); //=> 15
}

self.arrでアクセスした場合

実装.m
@synthesize arr;

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"arr : %@", arr);  //=> null
    self.arr = [[NSArray alloc] init];
    NSLog(@"arr retainCount : %d", [self.arr retainCount]); //=> 16
}

どういときにself付きでアクセスしたらよいの???

こういうとき

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"arr : %@", arr);  //=> null
    arr = [[NSArray alloc] init];
    
    self.arr = [NSArray array]; 
    NSLog(@"arr retainCount : %d", [self.arr retainCount]); //=> 16
}

すでに誰かがretain済みのものとかautoreleaseされるものを再代入(この表現でよいのか?)したとき。
つまり自分にオーナーシップがないものを代入するとき。


この場合にのみ、既に参照(代入)しているモノに対してreleaseし忘れることなく
新しいインスタンスを代入できる。

ちなみに
arr = [NSArray array];
NSLog(@"arr retainCount : %d", [self.arr retainCount]); //=> 16

の場合も参照カウントは変わっていないが、releaseをし忘れていることになる。