Обработка возвращаемого значения object_getIvar (объект id, Ivar ivar) - PullRequest
1 голос
/ 01 августа 2009

1) object_getIvar (объект id, Ivar ivar) возвращает идентификатор, если Ivar является объектом, например. если переменная является NSString, предположительно id = NSString, которая содержит значение. Это верно? Или что мне нужно сделать, чтобы получить доступ к значению Ивара.

2) если Ivar является float / int и т. Д. Что будет возвращено и как я могу преобразовать его во что-то, что я могу использовать (float или int хорошо, так как я могу использовать NSNumber numberWithXXX для преобразования его в объект) .

Ответы [ 2 ]

1 голос
/ 17 октября 2017

Пример использования для печати описания произвольных объектов:

- (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;
}
1 голос
/ 01 августа 2009

1) Правильно. Как указано в документах :

Возвращаемое значение
Значение переменной экземпляра, заданное ivar, или nil, если object - nil.

2) Независимо от типа ивара, вы всегда получите значение, которое имеет ивар. Вы можете определить тип Ivar, используя ivar_getTypeEncoding . Здесь есть список кодировок различных типов здесь .

Имея эту информацию под рукой, вы сможете написать переключатель, который обрабатывает каждый случай соответствующим образом; e.g.:

( предупреждение : непроверенный код впереди)

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...