1

1) object_getIvar(id object, Ivar ivar) は、Ivar がオブジェクトの場合、「id」を返します。変数が NSString の場合、おそらく値を含む id = NSString です。あれは正しいですか?または、Ivar の値にアクセスするにはどうすればよいでしょうか。

2) Ivar が float/int などの場合、返されるものと、それを使用できるものに変換する方法 (NSNumber numberWithXXX を使用してオブジェクトに変換できるため、float または int で問題ありません)。

4

2 に答える 2

1

1) 正しい。ドキュメントで述べたように:

戻り値
ivar で指定されたインスタンス変数の値、または object が nil の場合は nil。

2) Ivar の型に関係なく、常に Ivar が保持する値を取得します。ivar_getTypeEncodingを使用して、Ivar のタイプを判別できます。さまざまなタイプのエンコーディングのリストがここにあります

その情報が手元にあれば、それぞれのケースを適切に処理するスイッチを作成できるはずです。例えば:

(警告: テストされていないコードが先にあります)

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
}
于 2009-08-01T13:29:54.573 に答える
1

任意のオブジェクトの説明を印刷するための使用例:

- (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;
}
于 2017-10-17T20:38:56.480 に答える