メソッド

メソッドはMethod型で定義され,ランタイムAPIを以下のように追いかけていくと,

@objc-class.h

typedef struct class-method *Method

同じく@objc-class.h

struct class-method {
    SEL method_name;
    char *method_types;
    IMP method_imp;
}

となってて,

  • メソッド名(セレクタ)を表すSEL型の変数
  • メソッドへの引数を表すchar型の変数
  • メソッドの実装部分へのポインタを表すIMP型の変数

で構成される構造体にたどり着く.

クラスの書き方

クラスは通常インターフェース部と実装部を別々のファイルに記述する.
インターフェースは拡張子.hのインターフェースファイルに記述する.
実装部は拡張子.mの実装ファイルに記述する.
ひとつのファイルに複数のクラスを記述することが可能であるが,通例として1ファイル/1クラスとし,ファイル名は通常,記述されているクラス名と同じにする.
ルートクラスはNSObjectで,あらゆるクラスはNSObjectを根にもつ木構造にぶらさがる感じになっている.

インターフェース

↓こんな感じで書く

@interface Class:SuperClass
{
 var;
 ・・・
}
method
・・・
@end

クラス名は大文字から,変数,メソッド名は小文字からはじめるのが通例.

インターフェースファイルのインポート

↓こんな感じで記述する.

#import "Rectangle.h"

Objective-Cでは#includeの代わりに主に#importを使う.多重呼び出しを防いでくれる.
スーパークラスをインポートすることで,NSObjectからそのスーパークラスまですべての派生クラスの宣言を暗黙のうちに含む.
インターフェイスがその階層以外のクラスを記述している場合は,それらを明示的にインポートするか,@classディレクティブで宣言する必要がある.

インターフェースファイルの役割
  • クラスが継承階層にどのように結び付いていて、どのようなクラスが他に必要となるか(継承するか、クラスのどこかで参照するか)をユーザに知らせる.
  • オブジェクトに含まれているインスタンス変数をコンパイラに知らせ,サブクラスが継承している変数をプログラマに知らせる.
  • メソッド宣言のリストを通して,他のモジュールに,どのようなメッセージをクラスオブジェクトとクラスインスタンスに送信できるかを知らせる.クラス実装の内部で使用するメソッドは省略可.

インスタンス変数は,インターフェイスファイルで宣言する必要がある.
コンパイラがオブジェクトが定義されている場所だけでなく,オブジェクトが使用される場所でもオブジェクトの構造を認識している必要があるから.

クラスの実装

↓こんな感じで書く.

@implement Class:SuperClass
{
 var;
}
method
@end

すべての実装ファイルは,自身のインターフェースファイルをインポートしなければならない.
変数宣言とスーパークラス名は省略可.

インスタンス変数のスコープ

インスタンスの生成

インスタンスはクラスにallocメソッドを送って生成する.

[class alloc];

allocメソッドで生成した段階では,メモリの領域が確保されるだけで実体はない.
主にinitまたはinitではじまるイニシャライズ用メソッドにより実体が生成される.

[[class alloc] init];