工場裏のアーカイブス

素人によるiPhoneアプリ開発の学習記 あと機械学習とかM5Stackとか

プロパティ宣言の様々な書き方について

Objective-Cにおけるプロパティ宣言についてですが、XCode のバージョンアップなどに伴って様々な書き方が出来るようになっているようですので、簡単にまとめてメモしてみます。

最も基本的(であると思われる)な方法

まずは、一番基本的であると思われる方法でプロパティを用いたプログラムを書いてみます。

#import <Foundation/Foundation.h>

@interface myClass : NSObject{
    int num;
}

@property int number;

@end


@implementation myClass

@synthesize number = num;

-(void)showNumber{
    NSLog(@"num = %i\n", num);
}

@end


int main(int argc, const char * argv[])
{
    myClass *mc = [[myClass alloc] init];
    mc.number = 1;
    [mc showNumber];

    return 0;
}

最初にクラスのインタフェース部で、インスタンス変数(ここでは num)と、それにアクセスするためのプロパティ(ここでは number)を宣言します。そして実装部で、@synthesize 指示子を用いて以下のように、インスタンス変数とプロパティを対応させます。

@synthesize number = num;

これで以下のようにドット演算子を用いて、number プロパティを介して変数 num に外からアクセスすることが可能となります(ただし、変数 mc を id 型にしてしまうとドット演算子が使えないことに注意。型としてクラスを明示的に指定する必要があります)。

mc.number = 1;

 

変数名とプロパティ名が同一の場合

変数名とプロパティ名を同一にすれば、@synthesize 指定子を用いるときに、イコール演算子(=)を用いる必要が無くなります。

#import <Foundation/Foundation.h>

@interface myClass : NSObject{
    int number;
}

@property int number;

@end


@implementation myClass

//イコール演算子(=)を用いる必要はなし!
@synthesize number;

-(void)showNumber{
    NSLog(@"num = %i\n", number);
}

@end


int main(int argc, const char * argv[])
{
    myClass *mc = [[myClass alloc] init];
    mc.number = 1;
    [mc showNumber];

    return 0;
}

 

インスタンス変数の定義の省略

実は、プロパティだけを宣言して @synthesize 指定子を用いると、宣言したプロパティと同名、同型のインスタンス変数が裏側で自動的に定義されるようです。すなわち、インスタンス変数の定義を省略することが出来ます。

このインスタンス変数には、もちろんプロパティを介してアクセスすることが可能です。

#import <Foundation/Foundation.h>

@interface myClass : NSObject

//インスタンス変数は定義しない。プロパティのみ宣言!
@property int number;

@end


@implementation myClass

@synthesize number;

-(void)showNumber{
    //int 型のインスタンス変数 number が、自動的に生成されている。
    NSLog(@"num = %i\n", number); 
}

@end


int main(int argc, const char * argv[])
{
    myClass *mc = [[myClass alloc] init];
    mc.number = 1;
    [mc showNumber];

    return 0;
}

 

@synthesize 指定子の省略

更にXCode 4.4からは、インスタンス変数の定義に加えて、@synthezie 指定子すら省略出来るようです。このときは、宣言したプロパティと同型で、プロパティ名の頭にアンダーバー(_)が付けられた名前のインスタンス変数が自動的に定義されるようです。

もちろん、このアンダーバーが付いたインスタンス変数にも、プロパティを介してアクセスすることが可能です。@synthesize 指定子を省略した(かつ、@dynamic 指定子も用いていない)場合には、@synthesize 指定子が裏側で自動的に補完されるようです。

#import <Foundation/Foundation.h>

@interface myClass : NSObject

//インスタンス変数は定義しない。プロパティのみ宣言!
@property int number;

@end


@implementation myClass

//@synthesize 指定子も省略!

-(void)showNumber{
    //int 型のインスタンス変数 _number が、自動的に生成されている。
    //アンダーバー(_)が名前の頭に付くことに注意!
    NSLog(@"num = %i\n", _number);
}

@end


int main(int argc, const char * argv[])
{
    myClass *mc = [[myClass alloc] init];
    mc.number = 1;
    [mc showNumber];

    return 0;
}