インスタンス変数


HOME > TIPS > 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 型を表しているんだ。