2009-08-01 15 views
1

1)object_getIvar(idオブジェクト、Ivar ivar)は、Ivarがオブジェクトの場合は 'id'を返します。 variabeがNSStringの場合、おそらく値を含むid = NSStringです。あれは正しいですか?またはIvarの価値にアクセスするためには何が必要ですか。object_getIvar(idオブジェクト、Ivar ivar)の戻り値の扱い

2)Ivarがfloat/intなどの場合、何が返されるのか、どのように変換できますか(floatまたはintはNSNumberのnumberWithXXXを使用してオブジェクトに変換できます)。

答えて

1

1)正解。 docsにより述べたように:

戻り値
IVARによって指定されたインスタンス変数の値、またはゼロのオブジェクトがゼロである場合。

2)Ivarの種類にかかわらず、Ivarには常に価値があります。 ivar_getTypeEncodingを使用してIvarのタイプを決定することができます。さまざまなタイプのエンコーディングのリストがありますhere

この情報を参考にして、適切に各ケースを処理するスイッチを作成する必要があります。例えば:

警告:前方非試験コード)

const char* typeEncoding = ivar_getTypeEncoding(var); 

switch (typeEncoding) { 
    case '@': { 
     // handle class case 
    } break; 

    case 'i': { 
     // handle int case 
    } break; 

    case 'f': { 
     // handle float case 
    } break; 

    // .. and so on 
} 
+3

これは、おそらく確実に動作することができません。どのように異なる型が返されるかはABIによって異なり、すべての型で必ずしも同じであるとは限りません。私は真剣にこれがx86上の構造体で動作するかどうか疑問に思う。 – Chuck

+2

@Chuckドキュメントは明確ではありませんが、正しい使用法は 'object_getIvar()'を 'objc_msgSend()'のような正しい型を返す関数ポインタに実際にキャストすることです。例えば、 'CGRect' ivarを得るには' CGRect rect =(CGRect(*)(id、Ivar))object_getIvar)(object、ivar) 'のような呼び出しが必要です。コンパイラは正しい呼び出し規約でコードを出力します。 –

+1

奇妙なことに、Apple clang 4.1では、** 32ビットと64ビットの浮動小数点数を除き、すべての基本型(1、2、4、8バイトの符号付きおよび符号なし整数)が期待通りに返されます。それらを得るには、32ビットまたは64ビットの符号なし整数であるかのようにそれらを抽出し、適切な型にキャストしなければなりません。奇妙な。 –

0

例は、任意のオブジェクトの記述を印刷するために使用する:

- (NSString *) qCustomDescription 
{ 
    static int depth = 0; 

    NSMutableString *resultString = [NSMutableString stringWithFormat: @"<%@: %p>", NSStringFromClass([self class]), self]; 

    uint32_t ivarCount; 
    Ivar *ivars = class_copyIvarList([self class], &ivarCount); 

    if(ivars) 
    { 
     ++depth; 
     [resultString appendString: @"\n"]; 

     for(int tabs = depth; --tabs > 0;) 
      [resultString appendString: @"\t"]; 

     [resultString appendString: @"{"]; 

     for(uint32_t i = 0; i < ivarCount; ++i) 
     { 
      Ivar ivar = ivars[i]; 
      const char* type = ivar_getTypeEncoding(ivar); 
      const char* ivarName = ivar_getName(ivar); 
      NSString* valueDescription = @""; 
      NSString* name = [NSString stringWithCString: ivarName encoding: NSASCIIStringEncoding]; 

      switch(type[0]) 
      { 
       case '@': 
       { 
        id v = object_getIvar(self, ivar); 
        if(v) 
        { 
         if([self respondsToSelector: @selector(qDescriptionForValue:)]) 
          valueDescription = [self performSelector: @selector(qDescriptionForValue:) withObject: v]; 
         else 
          valueDescription = [v description]; 
        } 
        break; 
       } 

       case 'c': 
       { 
        char v = ((char (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%c", v]; 
        break; 
       } 

       case 'i': 
       { 
        int v = ((int (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%i", v]; 
        break; 
       } 

       case 's': 
       { 
        short v = ((short (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%d", v]; 
        break; 
       } 

       case 'l': 
       { 
        long v = ((long (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%ld", v]; 
        break; 
       } 

       case 'q': 
       { 
        long long v = ((long long (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%lld", v]; 
        break; 
       } 

       case 'C': 
       { 
        unsigned char v = ((unsigned char (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%uc", v]; 
        break; 
       } 

       case 'I': 
       { 
        unsigned int v = ((unsigned int (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%u", v]; 
        break; 
       } 

       case 'S': 
       { 
        unsigned short v = ((unsigned short (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%u", v]; 
        break; 
       } 

       case 'L': 
       { 
        unsigned long v = ((unsigned long (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%lu", v]; 
        break; 
       } 

       case 'Q': 
       { 
        unsigned long long v = ((unsigned long long (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%llu", v]; 
        break; 
       } 

       case 'f': 
       { 
        float v = ((float (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%f", v]; 
        break; 
       } 

       case 'd': 
       { 
        double v = ((double (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%f", v]; 
        break; 
       } 

       case 'B': 
       { 
        BOOL v = ((BOOL (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%@", v ? @"YES" : @"NO"]; 
        break; 
       } 

       case '*': 
       { 
        char *v = ((char* (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"%s", v]; 
        break; 
       } 

       case '#': 
       { 
        id v = object_getIvar(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"Class: %s", object_getClassName(v)]; 
        break; 
       } 

       case ':': 
       { 
        SEL v = ((SEL (*)(id, Ivar))object_getIvar)(self, ivar); 
        valueDescription = [NSString stringWithFormat: @"Selector: %s", sel_getName(v)]; 
        break; 
       } 

       case '[': 
       case '{': 
       case '(': 
       case 'b': 
       case '^': 
       { 
        valueDescription = [NSString stringWithFormat: @"%s", type]; 
        break; 
       } 

       default: 
        valueDescription = [NSString stringWithFormat: @"UNKNOWN TYPE: %s", type]; 
        break; 
      } 

      [resultString appendString: @"\n"]; 

      for(int tabs = depth; --tabs >= 0;) 
       [resultString appendString: @"\t"]; 

      [resultString appendFormat: @"%@: %@", name, valueDescription]; 
     } 

     [resultString appendString: @"\n"]; 

     for(int tabs = depth; --tabs > 0;) 
      [resultString appendString: @"\t"]; 

     [resultString appendString: @"}"]; 
     --depth; 

     free(ivars); 
    } 

    return resultString; 
} 
関連する問題