Handling the return value of object_getIvar(id object, Ivar ivar)

孤街浪徒 提交于 2019-12-24 07:16:08

问题


1) object_getIvar(id object, Ivar ivar) returns an 'id' if the Ivar is an object eg. if the variabe is an NSString, presumably the id = NSString which contains the value. Is that correct? Or what do I need to do to access the value of the Ivar.

2) if the Ivar is a float/int etc. what will get returned and how do I convert it into something I can use (a float or int is fine as I can use NSNumber numberWithXXX to convert it to an object).


回答1:


1) Correct. As stated by the docs:

Return Value
The value of the instance variable specified by ivar, or nil if object is nil.

2) No matter the type of the Ivar you will always get the value that the Ivar holds. You can determine the type of the Ivar by using ivar_getTypeEncoding. There's a list of the various type encodings here.

With that information at hand, you should be able to write a switch that handles each case appropriately; e.g.:

(warning: non-tested code ahead)

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
}



回答2:


Example use for printing the description of arbitrary objects:

- (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;
}


来源:https://stackoverflow.com/questions/1216262/handling-the-return-value-of-object-getivarid-object-ivar-ivar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!