最終更新:2013-01-10 (木) 10:17:29 (4122d)  

Objective-C/プロパティ
Top / Objective-C / プロパティ

変数ごとにいちいちアクセッサかいてたら面倒なので、プロパティという仕組みが用意されている。

@property float value;

は下記と同じ。

 - (float)value;
 - (void)setValue:(float)newValue;

概要

@property

  • .h(@interface)でプロパティを宣言
    @property NSString *userName;
    //@property (copy, nonatomic) NSString *userName;

@synthesize/@dynamic

合成されるアクセッサ

  • コンパイラは次の2つのアクセサメソッドを自動的に生成
    - (NSString *)userName
    - (void)setUserName:(NSString *)newUserName

インスタンス変数

  • インスタンス変数も宣言していない場合は自動的に生成される
    • 特に指定しなければ、合成されるインスタンス変数の名前は、プロパティ名の先頭にアンダースコアを置いたものになる
  • プロパティの実装にインスタンス変数を用いる場合、どの初期化メソッドでも適切に設定されるようにする必要がある

重要

  • 次のように、インスタンス変数名を指定せずに@synthesizeを記述することもできる。
    @synthesize firstName;
  • この場合、インスタンス変数名はプロパティ名と同じになる
  • この例では、インスタンス変数名もアンダースコアのない「firstName」となる。

書き方

Xcode 4.4

  • @synthesize@dynamicも書かなかった場合には@synthesizeを付けたのと同じ扱いとなる
    // ViewController.h
    @property (strong) NSString* testString;
    
    // ViewController.m
    @synthesize testString;//@synthesize testString = _testString;
  • // ViewController.h
    @property NSString* testString;//インスタンス変数名は_testString
  • デフォルトがstrongなので書かなくてよくなった
  • 特に指定しなければ、合成されるインスタンス変数の名前は、プロパティ名の先頭にアンダースコアを置いたものになる

インスタンス変数の省略 (Modern Runtimeのみ)

  • There are differences in the behavior of accessor synthesis that depend on the runtime:
    • For the legacy runtimes, instance variables must already be declared in the @interface block of the current class. If an instance variable of the same name as the property exists, and if its type is compatible with the property’s type, it is used—otherwise, you get a compiler error.
    • For the modern runtimes, instance variables are synthesized as needed. If an instance variable of the same name already exists, it is used.
  • iOS always uses the modern runtime so you never need to declare ivars explicitly.
    • that's either iOS 3.x or greater, or 64-bit Snow Leopard or greater
  • クラスでインスタンス変数を宣言していない場合、コンパイラが合成する
    // ViewController.h
    @interface ViewController : UIViewController{
    NSString* testString;
    }
    @property (strong) NSString* testString;
    
    // ViewController.m
    @synthesize testString;
  • // ViewController.h
    @property (strong) NSString* testString;
    
    // ViewController.m
    @synthesize testString;

古い書き方

  • インスタンス変数、@property@synthesizeが必要
    //プロパティの属性を宣言@interface(.h)のほうに書く
    @interface HogeObject:NSObject{
        NSString *hoge, *huga;
    }
    @property(copy,readwtire) NSString *hoge,*huga;
    @end
    
    //@implementationのほう(.m)に書く
    @implementation HogeObject
    @synthesize hoge,huga; 
    //@dynamicとした場合は、@propertyで宣言しても自前で実装する(アクセサが生成されない)
    //@synthesize hoge= _hogeValue;//アクセサ名(hoge)とインスタンス変数名(_hogeValue)とを変えるとき
    @end

メモ

  • ブール型(値がYESまたはNO)のプロパティには、ゲッタメソッドを「is」で始まる名前にする慣習がある
    @property (getter=isFinished) BOOL finished;