インスタンス変数やインスタンスメソッドは、インスタンスが存在しなければ呼び出すことはできませんでした。 これらは、インスタンスに関連付けられてメモリが個別に割り当てられるため当然のことです。
クラスメソッドは、逆にインスタンスには関係なく、クラスそのものに直結しているメソッドです。 メソッドはインスタンスと関連していないため、事実上グローバル関数と変わりません。 違うのは、呼び出すときにメッセージ式を使ってメッセージを介して呼び出す必要があるというところです。
クラスメソッドを宣言するのは、メソッドの宣言時に指定していたマイナス記号 - をプラス記号 + に置き換えるだけで、後はインスタンスメソッドと同じです。 ただし、クラスメソッドにはインスタンスが存在しないため、暗黙の self オブジェクトを使うことはできません。
メッセージ式からクラスメソッドを呼び出すには、インスタンスではなくクラス名を指定します。 これまで、alloc クラスメソッドを使ってきたことがあるので、クラスメソッドの呼び出し方については説明不要でしょう。
#import <stdio.h> #import <objc/Object.h> @interface Test : Object + (void)Write; @end @implementation Test + (void)Write { printf("I love you... so please do not love me.\n"); } @end int main() { [Test Write]; return 0; }
このプログラムの Test クラスで宣言されている Write メソッドは + が指定されているためクラスメソッドであると判断できます。 クラスメソッドの呼び出しにはインスタンスは不要なので main() 関数では [Test Write] という形でクラスに対してメッセージを送信しています。
インスタンスメソッドに対してクラスメソッドが存在するのであれば、インスタンス変数に対してクラスに直結するクラス変数があってもよいと思うかもしれません。 Java プログラマなどには static メソッド、静的なメソッドと表現したほうが分かりやすいでしょう。
実は、Objective-C にはクラス変数は存在しません。 そのクラスのすべてのインスタンスが共有する変数というものがほしい場合、クラスを宣言するヘッダファイル内にファイルスコープのグローバル変数を用意し、このグローバル変数をインスタンスメソッドなどからアクセスするという形でクラス変数を実現します。