§1 クラスメソッドとインスタンスメソッド
前回と同様のコードを使ってクラスメソッドとインスタンスメソッドついて説明したいと思います。
ヘッダファイル(TestClass.h)
1 2 3 4 5 6 7 8 9 10 |
#import <Foundation/Foundation.h> //クラス宣言部 @interface TestClass : NSObject{ NSString *myString; } - (void)setMyString :(NSString*)inputString; - (void)printString; @end |
クラスファイル(TestClass.m)
1 2 3 4 5 6 7 8 9 10 11 12 |
#import "TestClass.h" //クラス実装部 @implementation TestClass - (void)setMyString :(NSString*)inputString { myString = inputString; } - (void)printString { printf("myString is %s ", [myString UTF8String]); } @end |
メインファイル(main.m)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#import <Foundation/Foundation.h> #import "TestClass.h" int main(int argc, constchar *argv[]) { @autoreleasepool { // insert code here... id testClassObj; testClassObj = [[TestClass alloc] init]; [testClassObj setMyString:@"ABCDEFG"]; [testClassObj printString]; } return 0; } |
さて、main関数に記述されているこの部分に注目してください。
1 |
testClassObj = [[TestClass alloc] init]; |
最初に[TestClass alloc]にてインスタンスを生成していますが、TestClassはインスタンスではなくクラスです。インスタンスを生成せずにメソッドallocを呼び出しています。このようなメソッドをクラスメソッドと呼びます。これに対してインスタンスを生成して呼び出すメソッドはインスタンスメソッドと呼びます。
この2つメソッドの違いは、メソッド定義時に頭に付ける記号で区別します。「-」で始まるものはインスタンスメソッド、「+」で始まるものがクラスメソッドになります。
クラスメソッドは、インスタンスを生成せずにクラスから直接使用するので、インスタンスメソッドとは異なる性質を持っています。インスタンスを生成していないので、インスタンス変数、インスタンスメソッドを使うことはできません。
ということからクラスメソッドは汎用性が高いメソッドとなるのが普通で、渡される引数の値などだけで処理が完了するようなカンジになります。単純な計算処理や初期化処理などはクラスメソッドとして実装することができると思います。
§2 コンビニエンスコンストラクタ
クラスメソッドとして実装すると便利なメソッドがあります。「コンビニエンスコンストラクタ」というものです。コンビニエンスコンストラクタは単純に「インスタンスを作って返すためのクラスメソッド」です。これがどう便利なのかは以下のコードを見て下さい。前回のコードにコンビニエンスコンストラクタを追加して、改修したものです。
ヘッダファイル(クラス名.h)
1 2 3 4 5 6 7 8 9 10 |
#import <Foundation/Foundation.h> //クラス宣言部 @interface TestClass : NSObject{ NSString* myString; } + (TestClass*)testClassWithString:(NSString*)str; - (void)setMyString :(NSString *)inputString; - (void)printString; @end |
クラスファイル(クラス名.m)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#import "TestClass.h" //クラス実装部 @implementation TestClass + (TestClass*)testClassWithString:(NSString*)str { TestClass* testClassObj = [[selfalloc] init]; [testClassObj setMyString:str]; return testClassObj; } - (void)setMyString :(NSString *)inputString { myString = inputString; } - (void)printString { printf("myString is %s ", [myString UTF8String]); } @end |
メインファイル(main.m)
1 2 3 4 5 6 7 8 9 10 11 12 |
#import <Foundation/Foundation.h> #import "TestClass.h" int main(int argc, constchar * argv[]) { @autoreleasepool { // insert code here... id testClassObj = [TestClass testClassWithString:@"ABCDEFG"]; [testClassObj printString]; } return 0; } |
追加・変更した部分を説明します。
●ヘッダファイルにコンビニエンスコンストラクタの宣言を追加
1 |
+ (TestClass*)testClassWithString:(NSString*)str; |
クラスメソッドなので「+」で始まります。引数のstrはインスタンス変数myStringへセットされます。
●クラスファイルにコンビニエンスコンストラクタを実装
1 2 3 4 5 |
+ (TestClass*)testClassWithString:(NSString*)str { TestClass* testClassObj = [[self alloc] init]; [testClassObj setMyString:str]; return testClassObj; } |
[self alloc]の「self」は自身のことを表します。クラスメソッド内であればそのクラス自身、インスタンスメソッド内であればそのインスタンス自身のことです。つまり[TestClass alloc]と同じ意味になります。
●メインファイルをコンビニエンスコンストラクタを使用してインスタンス生成、初期化するように変更
1 |
id testClassObj = [TestClass testClassWithString:@"ABCDEFG"]; |
コンビニエンスコンストラクタを実装するとインスタンス生成が簡単になりコード量もグッと減ります。この1行でインスタンス生成とインスタンス変数への値セットを行っています。
以上のようにコンビニエンスコンストラクタを利用するとインスタンス生成部分を簡単に記述することができます。
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)- プロトコル」