なんでプロトコル使っているとiPod touchで死ぬんだろうか
というところから、Objective-C 2.0で「プロトコルの強化」がされたことがキーワードになっていると睨み、ちょっとどのように強化されたのさぁ〜ぁも〜ぅと調べはじめた。
そしたらビックリ!メソッドを実装してもしなくてもよいという@optionalというものが追加されたんだと。このゆるさ、Javaのinterfaceと如何に考え方が違うかを物語ってますね。
で、この@optionalか@requiredがコンパイル時アノテーションとしての機能しかもたないのであれば良いのですが、バイナリにも影響するんじゃないかしら。RTTIとしては情報を持っていてもおかしくない…というか、NSObjCRuntime.hというヘッダファイルに、以下のように実行時調査可能な関数が追加されているではないかっ!
FOUNDATION_EXPORT NSString *NSStringFromProtocol(Protocol *proto) AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
さっそくCocoaアプリで結果をダンプしてみた。GUIはいらんのでmain.mからNSApplicationはつぶして以下のようにして実行。
@protocol Test @required -(void)zettaiJisso; @optional -(void)docchidemoYoi; @end int main(int argc, char *argv[]) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @try { NSString *s = NSStringFromProtocol(@protocol(Test)); NSLog(s); return 0; //return NSApplicationMain(argc, (const char **) argv); } @finally { [pool release]; } }
で、実行結果ログは!
Test
って名前だけ〜!どんだけ〜!
…と悲観することもないような気がしてきた。この関数が実装されたのはヘッダの宣言にもある通り、Leopardからだ。即ちObjective-C 2.0からということになる。それまではプロトコルに関してはコンパイル時のみの静的評価で、RTTIは持っていなかったのではないかと考えられる。となるとやはりバイナリがiPod touch内の、non 2.0なRuntimeでは解釈不能になって落ちたと考えられるのだ!
のってきた。これは絶対コンパイルオプションだな。探してみることにする。
追記
タイムオーバー。勝手ビルド環境のせいかな。やっぱりだまってSDK出るの待つしか無いのか。