2013年9月5日木曜日

Objective-Cの勉強(8):id型よりクラス名 *の方が安全



id型よりクラス名 *の方が安全



クラスの型としてはid型が汎用的で使いやすいが、逆に言えば型(クラス)が特定出来ないので、
持っていないはずのメソッドを呼び出してしまったりする可能性がある。

それを動的に調べる方法もあるのだが、コンパイラレベルでもある程度チェックできる。
素直に元のクラス名のアドレス型で宣言すればよいだけである。
これはコンパイルレベルのチェックを強化させるだけなので、実行時には全く影響を与えない。

@interface A : NSObject
- (void) Write;
@end
@implementation A
- (void) Write
{
    printf("Write\n");
}
@end
int main()
{
    id obj1 = [A new];      // クラスAにはWriteというメソッドが存在するが、
    id obj2 = [NSObject new]; // 親クラスであるNSObjectにはない(場合)

    [obj1 Write];
    [obj2 Write];   // 実行時にエラーとなる
    [obj1 ObjFree]
    [obj2 ObjFree]
    return(0);
}
↓これを明示的なクラス名で記述する。
int main()
{
    A * obja = [A new]; // idは元々ポインタを示す型なので、クラス名で明示する時は"*"が必須
    [obja Write];       // もしクラスAがWriteメソッドを持たない場合は、コンパイル時にエラーになる
    [obja ObjFree];
    return(0);
}
この場合は呼び出す元となるインスタンスが固定されているので、メソッドの存在があらかじめ解るが、Objective-Cでは逆に、メソッド名自体=メッセージを固定して呼び出し対象とするインスタンスを変更していく;送るメッセージは同じだが、それを解釈するオブジェクトが違う、という記述をよく行う。その場合はこの方法は使えない。

その「動的なメソッドの存在チェック方法」については後述。

0 件のコメント:

コメントを投稿