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で良い。

補足

クラス拡張とカテゴリは厳密には違う機能である。詳しくは下記を参照。

Objective-Cのクラス・カテゴリ・クラス拡張の整理 - $ cat /var/log/shin