[Objective-C] プロパティの属性のメモ

プロパティはインスタンスのアクセサをお手軽に記述するためのもの

プロパティの属性

  • readwrite(デフォルト), readonly
    ゲッタのアクセス制限についての属性。読んで時のごとく。

  • assing(デフォルト)
    セッタの属性。参照カウンタにはなんら干渉しない。

    - (void)setXxx : (***)obj {
    xxx = obj;
    }
    
  • retain
    セッタの属性。渡されたインスタンスを retain する。 渡される前に持っていたものは release する。

    - (void)setXxx : (***)obj {
    if( xxx != obj ) {
    [xxx release];
    xxx = obj;
    [xxx retain];
    }
    }
    
  • copy
    セッタの属性。渡されたインスタンスの copy メソッドの返すインスタンスをセットする。

    - (void)setXxx : (***)obj {
    if( xxx != obj ) {
    xxx = [obj copy];
    }
    }
    
  • getter=***, setter=***
    アクセサメソッドの名前。デフォルトでは xxx メンバへのゲッタ名は xxx, セッタ名は setXxx となる。

  • atomic(デフォルト), nonatomic 同期処理の有無

テキトーに動かす

下のコメントの部分を変更してiPhoneシュミレータで動かしてみる。

#import <UIKit/UIKit.h>

// プロパティのcopy属性を使うためにcopyWithZone
// を実装した Xクラス を定義
@interface X : NSObject
@end
@implementation X
- (id)copyWithZone:(NSZone*)zone {
    return [[[self class] allocWithZone:zone] init];
}
@end

@interface PropertyTestViewController : UIViewController {
  UILabel *label;
  X *xAssign, *xRetain, *xCopy;
}

@property (nonatomic, assign) X *xAssign;
@property (nonatomic, retain) X *xRetain;
@property (nonatomic, copy) X *xCopy;

@end

@implementation PropertyTestViewController

@synthesize xAssign, xRetain, xCopy;

- (void)viewDidLoad {
    [super viewDidLoad];

  // ここに処理を記述する
  ・・・

  label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 60)];
  label.text = [NSString stringWithFormat: @"Assign:%d, Retain:%d, Copy:%d", [xAssign retainCount], [xRetain retainCount], [xCopy retainCount]];
  [self.view addSubview:label];
}

- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];}
- (void)viewDidUnload {}
- (void)dealloc {[super dealloc];}

@end

// assign はそのまま渡す
// 参照カウンタには関係しない
self.xAssign = [[X alloc] init];

結果

Assign:1, Retain:0, Copy:0
// retain属性のプロパティにセットすると
// 渡されたインスタンスの参照カウントが増える
self.xRetain = [[X alloc] init];

結果

Assign:0, Retain:2, Copy:0
// これはプロパティのメソッドによるアクセスではない
// つまり assign と同等な代入になる
xRetain = [[X alloc] init];

結果

Assign:0, Retain:1, Copy:0
// assign は参照カウンタには何もしない
//  もともと持っていたインスタンスの relese もしない
self.xAssign = [[X alloc] init];
self.xRetain = [[X alloc] init];
self.xAssign = xRetain;
[xRetain release];

結果

Assign:1, Retain:1, Copy:0
// Copy
self.xAssign = [[X alloc] init];
self.xCopy = xAssign;
[xAssign retain];

結果

Assign:2, Retain:0, Copy:1
Share
関連記事