@selector って何?

iPhone デベロッパーズクックブックを読んでいこうとしているのですが、そもそも Objective-C 自体を理解できていないので、わからないところを調べながら進めます。

というわけで、@selector って何?と思って「詳解 Objective-C 2.0」の「07-02 メッセージ送信の仕組み」の「セレクタと SEL 型」と「メッセージ探索」を読んでみました。

そもそも、セレクタ == メッセージセレクタ == メソッド名。@selector はそのセレクタがコンパイル時に変換される内部表現を、プログラム上で扱えるようにするコンパイラ指示子とのこと。Objective-C では実行するメソッドは実行時に動的に決定されるということで、これを使うと動的にメソッドを呼び分けられるということです。

早速試してみます。

#import <Foundation/Foundation.h>
 
@interface MyObject1 : NSObject {
}
- (void)hello;
- (void)goodby;
- (void)goodMorning:(NSString*)firstName lastName:(NSString*)lastName;
@end
 
@implementation MyObject1
- (void)hello {
    NSLog(@"hello");
}
 
- (void)goodby {
    NSLog(@"goodby");
}
 
- (void)goodMorning:(NSString*)firstName lastName:(NSString*)lastName {
    NSLog(@"good morning, %@ %@", lastName, firstName);
}
@end
 
int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
    //
    // 現在の時間によりメソッドを呼び分ける
    //
    MyObject1* myObject1 = [[[MyObject1 alloc] init] autorelease];
    time_t now = time(0);
    struct tm* t = localtime(&now);
    SEL method = t->tm_hour < 12 ? @selector(hello) : @selector(goodby);
    [myObject1 performSelector:method];
 
    //
    // goodMorning メソッドを実装しているか調べる
    //
    NSString* msg = NULL;
    if ([myObject1 respondsToSelector:@selector(goodMorning:lastName:)]) {
        msg = [NSString stringWithCString:"goodMorning:lastName: is implemented"];
    } else {
        msg = [NSString stringWithCString:"goodMorning:lastName: is NOT implemented"];
    }
    NSLog(msg);
 
    [pool drain];
    return 0;
}

前の方では時間によって MyObject の hello メソッドと goodby メソッドを呼び分け、後ろの方では MyObject に goodMorning:lastName: メソッドが実装されているか調べています。

この例だといまいちこのメソッド呼び出しの動的な側面が表現できていないと思いますが、メソッドが実装されてさえいればそのオブジェクトが何であれ関係ないところは、メッセージの送信先を動的に変えたいところとかで便利そうですね。なるほど。

と思って iPhone デベロッパーズクックブックに戻ってみたら @selector でてきてなかったや。キャハ。


About this entry