Mac OS X と Objective-C 2.0 の Object クラス
Foundation Framework の NSObject じゃなくて Object クラスの話です.
久しぶりに昔書いた Objecive-C のコードを Mac OS X 上でいじってたら軒並み動かなかった.よくわからないので適当にテストコードを書いてみる.
#include <stdio.h> #include <objc/Object.h> @interface Hello : Object { char *message; } + newWithMessage:(const char *)message; - initWithMessage:(const char *)message; -(void)printMessage; @end @implementation Hello + newWithMessage:(const char *)aMessage { return [[self alloc] initWithMessage:aMessage]; } - initWithMessage:(const char *)aMessage { self = [super init]; message = aMessage; return self; } -(void)printMessage { printf("%s\n", message); } @end int main(int argc, char* argv[]) { id hello = [Hello newWithMessage:"Hello, Objective-C World!!"]; [hello printMessage]; return 0; }
こんな感じの hello.m を書いて以下のようにコンパイル.
$ gcc -o hello hello.m -lobjc hello.m: In function ‘+[Hello newWithMessage:]’: hello.m:21: warning: ‘Hello’ may not respond to ‘+alloc’ hello.m:21: warning: (Messages without a matching method signature hello.m:21: warning: will be assumed to return ‘id’ and accept hello.m:21: warning: ‘...’ as arguments.) hello.m: In function ‘-[Hello initWithMessage:]’: hello.m:25: warning: ‘Object’ may not respond to ‘-init’ hello.m:26: warning: assignment discards qualifiers from pointer target type
Object クラスにクラスメソッド alloc やメソッド init がないと警告がでる. 実行ファイルはできたので実行してみたら以下のようなエラーが出て動かない.
$ ./hello objc[73654]: Hello: Does not recognize selector forward:: Illegal instruction
alloc なかったらどうやってオブジェクト作ったらいいんだろう?
とりあえず /usr/include/objc/Object.h を見てみる.
#if __OBJC2__ @interface Object { Class isa; /* A pointer to the instance's class structure */ } +class; -(BOOL) isEqual:anObject; @end #else @interface Object { Class isa; /* A pointer to the instance's class structure */ } /* Initializing classes and instances */ + initialize; - init; /* Creating, copying, and freeing instances */ + new; + free; - free; + alloc; <略> @end
どうやら __OBJC2__ マクロが定義されているとメソッドが軒並みなくなるらしい… Objective-C 2.0 で GC が導入された関係かな?
試しに __OBJC2__ を未定義にしてコンパイルして実行してみる.
$ gcc -o hello hello.m -U__OBJC2__ -lobjc $ ./hello objc[74015]: Illegal instruction
コンパイル時に警告は出なくなったが実行時エラーが起きるのはかわらない. ヘッダだけをごまかしても同じライブラリを同じようにリンクしているなら当然の結果か…
Objective-C 2.0 じゃない状態(1.0?)でコンパイルするにはどうすればいいのかしら?