Objective-cのPrivate、Protected、Publicな変数及びメソッドについてまとめ
Objective-CでどのようにPrivate, Protected, Publicなインスタンス変数、プロパティ、メソッドを宣言するか纏める。
下記のテンプレをコピーして、#pragma mark
の該当部分に必要なものを記述する。
以下は、HogeClassを宣言する場合のテンプレである。
ファイルの構成
HogeClass.h
HogeClass_Protected.h
HogeClass.m
HogeClass.h
#import <Foundation/Foundation.h> @interface HogeClass : NSObject{ #pragma mark Private iVars @private // privateなインスタンス変数の宣言 #pragma mark Protected iVars @protected // protectedなインスタンス変数の宣言 #pragma mark Public iVars @public // publicなインスタンス変数の宣言 } #pragma mark Public Properties //Publicな@propertyを宣言する #pragma mark Public Mehotds //Publicなメソッドを宣言する @end
HogeClass_Protected.h
#import "HogeClass.h" @interface HogeClass () #pragma mark Protected Properties //Protectedな@propertyを宣言 #pragma mark Protected Methods //Protectedなメソッドを宣言 @end
HogeClass.m
#import "HogeClass.h" #import "HogeClass_Protected.h" @interface HogeClass() #pragma mark Private Methods //Privateな@propertyを宣言 #pragma mark Private Methods //Privateなメソッドを宣言 @end @implementation HogeClass #pragma mark - #pragma mark Public Method Implementation //Publicなメソッドの実装を記述 #pragma mark - #pragma mark Private Method Implementation //Privateなメソッドの実装を記述 #pragma mark - #pragma mark Protected Method Implementation //Protectedなメソッドの実装を記述 @end
インスタンス変数について
objective-cでClassのインスタンス変数を生成する場合は、次のようにコンパイラディレクティブを用いることで簡単にPrivate, Protected, Publicの使い分けができる。
@interface MyClass : NSObject { @private // privateなインスタンス変数 int privateVar; @protected // protectedなインスタンス変数 int protectedVar; @public // publicなインスタンス変数 int publicVar; } @end
@property
を利用した変数宣言の場合は、上記のような@private
修飾子のようなものが利用できない為別の手段で、privateやprotectedを実現する必要がある。
privateなプロパティ
例えば、BaseClassにbasePrivate
というPrivateなプロパティを宣言する場合を考える。ファイルの構成を
BaseClass.h
BaseClass.m
とする。それぞれの、中身は次のようになる。
BaseClass.h
#import <Foundation/Foundation.h> @interface BaseClass : NSObject //BaseClassのPublicプロパティ @property(strong,nonatomic) NSString *basePublic; @end
Baselass.m
#import "BaseClass.h" @interface BaseClass() //BaseClassのPrivateプロパティ @property(strong,nonatomic) NSString *basePrivate; @end @implementation BaseClass -(void)accessMethod; { self.basePrivate; self.basePublic; }
上記のコードで重要なのは、.m
ファイルの先頭に@interface
でプロパティを宣言していることである。BaseClassを利用する他のClassは、BaseClassを利用する際にBaseClass.h
ファイルをimportするので、BaseClass.m
に記述されたプロパティは利用できない。
protectedなプロパティ
次に、BaseClassにProtectedなプロパティbaseProtected
を宣言する場合を考える。ファイルは次の様になる。
BaseClass.h
BaseClass_Protected.h
BaseClass.m
SubClass.h
SubClass.h
BaseClass.h
#import <Foundation/Foundation.h> @interface BaseClass : NSObject //BaseClassのPublicプロパティ @property(strong,nonatomic) NSString *basePublic; @end
BaseClass_Protected.h
#import "BaseClass.h" @interface BaseClass () //BaseClassのProtectedなプロパティ @property(strong,nonatomic) NSString *baseProtected; @end
BaseClass.m`
#import "BaseClass.h" #import "BaseClass_Protected.h" @interface BaseClass() //BaseClassのPrivateプロパティ @property(strong,nonatomic) NSString *basePrivate; @end @implementation BaseClass -(void)accessMethod; { self.basePrivate; self.baseProtected; self.basePublic; } @end
SubClass.h
#import "BaseClass.h" @interface SubClass : BaseClass @end
SubClass.m
#import "SubClass.h" #import "BaseClass_Protected.h" @interface SubClass() //SubClassのPrivate @property(strong,nonatomic) NSString *subPrivate; @end @implementation SubClass -(void)acsessMethod; { //BaseClassのプロパティへのアクセス //self.basePrivate; self.baseProtected; self.basePublic; //SubClassのプロパティへのアクセス self.subPrivate; }
accessMethodは、説明の都合上加えてるだけで、気にしなくて良い。呼び出しもしないので、宣言も省略している。
accessMethodで、それぞれのプロパティ及びメソッドを参照している。コメントアウトしているのは、そのクラスからはアクセスできないものである。
重要なのは、
Protectedなプロパティを、別のファイルで宣言していること
Protectedなプロパティ用のファイル
BaseClass_Protected.h
をそのクラスとサブクラスの.m
ファイルでimportしていること
である。
Publicなプロパティ
.h
ファイルにて宣言すれば、Public扱いである為、省略する。
メソッドについて
基本的に宣言の仕方としては、プロパティと同じなので割愛する。
宣言したプロパティの実装場所は、全てBaseClass.mで良い。
補足
クラス拡張とカテゴリは厳密には違う機能である。詳しくは下記を参照。