HMDT - Logic and Intuition -

about HMDT

Cocoa Programming Tips 1001

Objective-C

インスタンス変数

Objective-C - インスタンス変数

クラスからインスタンス変数の定義を取り出す

Keywords: ivar

Class 型の構造体のは、インスタンス変数のリストへのポインタを持っているんだ。こいつをたどっていけば、インスタンス変数を表示することができるぜ。

まずは Class 型を見てみよう。objc_ivar_list 型の ivars というフィールドがあるんだ。

順に追っていこう。まず、Class 型の定義は /usr/include/objc/obj.c にある。

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

struct objc_class {
    ...
    struct objc_ivar_list *ivars;
    ...
};

これがインスタン変数のリストだ。objc_ivar_list の定義はこんな感じになっている。

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

struct objc_ivar_list {
    int ivar_count;
#ifdef __alpha__
    int space;
#endif
    struct objc_ivar {
        char *ivar_name;
        char *ivar_type;
        int ivar_offset;
#ifdef __alpha__
        int space;
#endif
    } ivar_list[1];    /* variable length structure */
};

ivar_count がインスタンス変数の数を表す。その数の分だけ、ivar_list の配列があるわけだ。ivar_list は objc_ivar 型であり、その中に、インスタンス変数の名前である ivar_name、インスタンス変数の型名である ivar_type とかがあるんだ。

クラスを指定して、その中のインスタンス変数を表示させるサンプルコードは、こんな感じになる。

showInstanceVariables() (sample)

void showInstanceVariables(Class klass)
{
    struct objc_ivar_list* ivars;
    Ivar ivar;
    int i;
    
    printf("class: %s?", klass->name);
    
    ivars = klass->ivars;
    if(ivars == nil) {
        printf("There is no ivars?");
        return;
    }
    
    // Show instance variables
    ivar = ivars->ivar_list;
    for(i = 0; i < ivars->ivar_count; i++) {
        printf("  ivar name: %s?", ivar->ivar_name);
        printf("  ivar type: %s?", ivar->ivar_type);
        printf("  ivar offset: %d?", ivar->ivar_offset);
        ivar++;
    }
}

この関数に Class を引き渡してやると、中のインスタンス変数を走査して、名前と型名とオフセットを表示するんだ。実行結果は、こんな感じ。たとえば NSResponder を渡すと、

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

class: NSResponder
  ivar name: _nextResponder
  ivar type: @
  ivar offset: 4

名前が _nextResponder っていうインスタンス変数が 1 つあって、その型名は @ だ。あとで説明するけど、@ は id 型を表しているんだ。

back to top content

Copyright © 2002-2006 HMDT. All rights reserved.