HMDT - Logic and Intuition -

about HMDT

Cocoa Programming Tips 1001

Objective-C

メソッド

Objective-C - メソッド

メソッドのリストにアクセスする

Keywords: class_nextMethodList

Class 型の構造体は、とうぜん、メソッドの定義も持っている。だけど、取り出すにはちょっと工夫が必要。Class 型の定義を見てみてくれ。メソッドの定義である、objc_method_list 型の methodLists というフィールドがあるんだけど、、、

/usr/include/objc/objc-class.h

struct objc_class {
    ...
    struct objc_method_list **methodLists;
    ...
};

ポインタのポインタになっていることからも想像できるように、こいつはメソッドのリストのリストだ。つまり、クラスのメソッドの定義は、複数のメソッドリストからできてるんだ。なんで、いくつかに分かれているのか?実行結果から推測すると、カテゴリごとに分かれているようだ(明確な記述がないから、あくまで推測)。

アクセスするには、専用の関数が用意されている(ポインタのポインタをインクリメントしてやっても、うまくいかなかった)。

/usr/include/objc/objc-class.h

OBJC_EXPORT struct objc_method_list *class_nextMethodList(Class, void **);

これを使えば、メソッドのリストのリストにアクセスできて、メソッドのリストを取り出すことができる。使用例は、こんな感じ。

showMethods() (sample)

    void* iterator = 0;
    struct objc_method_list* mlist;
    
    while(mlist = class_nextMethodList(klass, &iterator)) {
        Method method = mlist->method_list;
        ...
        }
    }

これで、メソッドのリストである、Method 型の method_list を取り出すことができるんだ。

Objective-C - メソッド

メソッドのリストからメソッドを取り出す

Keywords: Method

上のようにして、メソッドのリストを得たら、そこからメソッドのリストを取り出す。Method の定義は、

/usr/include/objc/objc-class.h

typedef struct objc_method *Method;

であって、じゃあ struct objc_method の定義はどうか、っていうと、

/usr/include/objc/objc-class.h

struct objc_method_list {
    struct objc_method_list *obsolete;

    int method_count;
#ifdef __alpha__
    int space;
#endif
    struct objc_method {
        SEL method_name;
        char *method_types;
        IMP method_imp;
    } method_list[1];    /* variable length structure */
};

こうだ。method_count でメソッドの数を調べて、その数だけ method_list がある。そこから method_name とか method_types とかが得られるんだ。

method_name の型である SEL 型の定義は、/usr/include/objc/objc.h にある。

/usr/include/objc/objc.h

typedef struct objc_selector *SEL;

じゃあ、struct objc_selector の定義は、、、ないぞ!?見つからないー。公開してないのか?てなわけで、他のドキュメントを探ると、SEL は char へのポインタで、その先は C の文字列になってるらしい(『ところで、セレクタってなんなのさ?』の項を参照)。

というわけで、クラスから、メソッドの名前と型を取り出して表示する、サンプルコード。

showMethods() (sample)

void showMethods(Class klass)
{
    void* iterator = 0;
    struct objc_method_list* mlist;
    int i;
    
    printf("class: %s?", klass->name);
    
    while(mlist = class_nextMethodList(klass, &iterator)) {
        Method	method = mlist->method_list;
        printf("method count: %d?", mlist->method_count);
        
        for(i = 0; i < mlist->method_count; i++) {
            printf("  method_name: %s?", (char*)method->method_name);
            printf("  method_types: %s?", method->method_types);
            method++;
        }
    }
}

これでメソッドの名前は分かる。次の問題は、メソッドの型だな。

back to top content

Copyright © 2002-2006 HMDT. All rights reserved.