§1 変数のスコープについて
クラスのインスタンス変数のスコープ(アクセス権)についての話です。
インスタンス変数はデフォルトではクラス外部からはアクセスできないように隠蔽されています。ではこれらを外部からアクセスできるようにするにはどうしたら良いでしょうか?Objective-Cではアクセス権に関するコンパイラディレクティブ(@〜)が用意されているので、それを使うことでインスタンス変数のアクセス権をコントロールすることができます。以下の3つのコンパイラディレクティブが用意されています。
@private
クラス外部からはアクセスできません。完全に隠蔽された状態です。インスタンス変数をクラス内だけで利用する場合に指定します。
@protected
クラス内部およびサブクラス内であればアクセスできます。デフォルトではこれが指定されています。
@public
クラス外部からも自由にアクセスできます。完全に公開された状態です。
指定の方法は以下のようになります。
1 2 3 4 5 6 7 8 |
@interface クラス { @public public変数 @protected protected変数 @private private変数 } |
コンパイラディレクティブを指定しない場合は@protectedを指定しているのと同じ状態になります。
クラスのインスタンス変数にアクセスするには「->」を使用します。こんなカンジでアクセスできます。
1 2 |
testClassObj = [[TestClass alloc] init]; testClassObj->myString = @"HIJKLMN" |
§2 プロパティ
インスタンス変数を@publicに指定すればアクセスが簡単になりますが、むやみに@public指定をするのはいささか乱暴な気がします。値を取得するメソッドと値を設定するメソッドをそれぞれ作成すれば問題ありませんが、これも少しメンドウです。そこでインスタンス変数にアクセスする方法として「プロパティ」が用意されています。これは値取得用メソッドと値設定用メソッドを自動的に生成してくれる便利な機能です。プロパティを利用するには以下のようにします。
●@interface内でプロパティを記述する。
@property (属性) データ型 プロパティ名;
【属性】
プロパティの性質を示す値を記述します。以下のような値が設定可能です。省略することもできます。
retain――オブジェクトを保持する
assign――オブジェクトを参照する
copy――オブジェクトをコピーして保持する
readwrite――読み書き可能(デフォルトではこれが設定される)
readonly――読み取り専用(これを指定すると値取得用メソッドのみ使用できる)
getter=メソッド名――値取得用メソッド名を明示的に指定(自分でメソッド名を命名したい時)
setter=メソッド名――値設定用メソッド名を明示的に指定(自分でメソッド名を命名したい時)
【データ型】
対象のインスタンス変数のデータ型を指定します。
【プロパティ名】
プロパティの名前を指定します。通常はインスタンス変数と同じ名前にします。
こんなカンジで記述します。
1 2 |
@property NSString* myString; //属性を省略 @property (readonly) NSString* myString; //属性を指定 |
●@implementation内に@synthesizeディレクティブを記述する。
@synthesize プロパティ名;
@propertyディレクティブでインスタンス変数と違う名前をプロパティ名にした場合は以下のようにします。
@synthesize プロパティ名 = インスタンス変数;
カンマで区切って複数のプロパティを記述することも可能です。
@synthesize プロパティ名1, プロパティ名2, プロパティ名3;
こんなカンジで記述します。
1 2 3 |
@synthesize myString; //プロパティ名はインスタンス変数と同じ @synthesize myProperty = myString; //プロパティ名をインスタンス変数とは違う名前に @synthesize myString1, myString2, myString3; //カンマで区切って複数プロパティを記述 |
これでプロパティが使用できるようになります。生成されるメソッドは
値取得用メソッド —- プロパティ名と同じ名前のメソッド
値設定用メソッド —- プロパティ名の前に「set」を付けたメソッド(setの次の文字は大文字になります)
例えば、インスタンス変数myStringに対してプロパティを
1 2 |
@property (retain)NSString* myString; @synthesize myString; |
と設定した場合は、値取得用メソッド「myString」と値設定用メソッド「setMyString」が生成されます。
以下のようにすればメソッド名を好きな名前にすることもできます。(setterのメソッドに「:」を付けるのを忘れないように)
1 |
@property (retain, getter = getMyString, setter = setMyString:)NSString* myString; |
プロパティへのアクセスはドット演算子「.」を使用します。
1 2 3 4 |
printf("myString is %s ", testClassObj.myString); //値取得(プロパティでアクセス) printf("myString is %s ", [testClassObj myString]); //値取得(値取得用メソッドでアクセス) testClassObj.MyString = @"OPQRSTU"; //値設定(プロパティでアクセス) [testClassObj setMyString:@"OPQRSTU"]; //値設定(値設定用メソッドでアクセス) |
以下はプロパティを使用してインスタンス変数にアクセスしている例です。
ヘッダファイル(TestClass.h)
1 2 3 4 5 6 7 8 9 10 |
#import <Foundation/Foundation.h> //クラス宣言部 @interface TestClass : NSObject{ NSString *myString; } @propertyNSString* myString; //プロパティを宣言(インスタンス変数と同じ名前) + (TestClass*)testClassWithString:(NSString*)str; @end |
クラスファイル(TestClass.m)
1 2 3 4 5 6 7 8 9 10 11 12 |
@implementation TestClass @synthesize myString; //アクセサ生成 +(TestClass*)testClassWithString:(NSString*)str { TestClass* testClassObj = [[selfalloc] init]; testClassObj.myString = str; //[testClassObj setMyString:str];でもOK //testClassObj->myString = str;でもOK return testClassObj; } @end |
メインファイル(main.m)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#import <Foundation/Foundation.h> #import "TestClass.h" int main(int argc, constchar * argv[]) { @autoreleasepool { // insert code here... TestClass *testClassObj = [TestClasstestClassWithString:@"ABCDEFG"]; //"mystring is ABCDEFG" printf("mystring is %s ", [testClassObj.myStringUTF8String]); //値取得(プロパティ) //"mystring is ABCDEFG" printf("mystring is %s ", [[testClassObj myString] UTF8String]); //値取得(メソッド) testClassObj.myString = @"HIJKLMN"; //値設定(プロパティ) //"mystring is HIJKLMN" printf("mystring is %s ", [testClassObj.myStringUTF8String]); [testClassObj setMyString:@"OPQRSTU"]; //値設定(メソッド) //"mystring is OPQRSTU" printf("mystring is %s ", [testClassObj.myStringUTF8String]); } return 0; } |
Objective-C 基礎 目次
以下の記事も参考にして頂ければと思います。
「Objective-C 基礎(1)- Xcodeのインストールとプロジェクトの作成」
「Objective-C 基礎(2)- Objective-Cの概要とメソッドの呼び出し」
「Objective-C 基礎(3)- クラス定義の方法」
「Objective-C 基礎(4)- クラスの使い方」
「Objective-C 基礎(5)- クラスメソッドとインスタンスメソッド」
「Objective-C 基礎(6)- 変数のスコープとプロパティ」
「Objective-C 基礎(7)- 変数のデータ型」
「Objective-C 基礎(8)- 文字列とNSStringクラス」
「Objective-C 基礎(9)- 可変文字列とNSMutableStringクラス」
「Objective-C 基礎(10)- Objective-Cの配列」
「Objective-C 基礎(11)- Objective-Cの連想配列」
「Objective-C 基礎(12)- ループ処理」
「Objective-C 基礎(13)- プロトコル」