IOS中自己关于Ivar和objc_property_t的理解,整理下网上资料

来源:互联网 发布:nightowl软件 编辑:程序博客网 时间:2024/06/07 02:53

常用的反射方式,有如下两种:

自定义实体类  转化为  NSDictionary

NSDictionary  转化为  自定义实体类


首先引用头文件   : 

#import <objc/runtime.h>

例子:

1、自定义实体类  转化为  NSDictionary

- (NSDictionary *)toDictionary{    NSMutableDictionary *dictionaryFormat = [NSMutableDictionary dictionary];        //  取得当前类类型    Class cls = [self class];        unsigned int ivarsCnt = 0;    // 获取类成员变量列表,ivarsCnt为类成员数量    Ivar *ivars = class_copyIvarList(cls, &ivarsCnt);        // 遍历成员变量列表,其中每个变量都是Ivar类型的结构体    for (const Ivar *p = ivars; p < ivars + ivarsCnt; ++p)    {        Ivar const ivar = *p;                // 获取变量名        NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];        // 若此变量未在类结构体中声明而只声明为Property,则变量名加前缀 '_'下划线        // 比如 @property(retain) NSString *abc;则 key == _abc;                // 获取变量值        id value = [self valueForKey:key];                // 取得变量类型        // 通过 type[0]可以判断其具体的内置类型        const char *type = ivar_getTypeEncoding(ivar);                if (value)        {            [dictionaryFormat setObject:value forKey:key];        }     }    return dictionaryFormat;}
2、NSDictionary  转化为  自定义实体类

+ (id)objectFromDictionary:(NSDictionary *)dictionary className:(NSString *)name

{

//name为 仅定义的属性的类名

    if (dictionary == nil || name == nil || name.length == 0) {

        return nil;

    }

    

    id object = [[NSClassFromString(name) alloc]init];

    

    @try {

        id classObject = objc_getClass([name UTF8String]);

        

        unsigned int count = 0;

        objc_property_t *properties = class_copyPropertyList(classObject, &count);

        Ivar * ivars = class_copyIvarList(classObject, nil);

        

        for (int i = 0; i < count; i ++)

        {

            NSString *memberName = [NSString stringWithUTF8String:ivar_getName(ivars[i])];

            const char *type = ivar_getTypeEncoding(ivars[i]);

            NSString *dataType =  [NSString stringWithCString:type encoding:NSUTF8StringEncoding];

            

            NSLog(@"Data %@ type: %@",memberName,dataType);

            

            JsonToModelDataType rtype = JsonToModelDataTypeObject;

            if ([dataType hasPrefix:@"c"])

            {

                // BOOL

                rtype = JsonToModelDataTypeBOOL;

            } else if ([dataType hasPrefix:@"i"])

            {

                // int

                rtype = JsonToModelDataTypeInteger;

            } else if ([dataType hasPrefix:@"f"])

            {

                // float

                rtype = JsonToModelDataTypeFloat;

            } else if ([dataType hasPrefix:@"d"])

            {

                // double

                rtype = JsonToModelDataTypeDouble;

            } else if ([dataType hasPrefix:@"l"])

            {

                // long

                rtype = JsonToModelDataTypeLong;

            }

            

            for (int j = 0; j < count; j ++)

            {

                objc_property_t property = properties[j];

                NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];

                NSRange range = [memberName rangeOfString:propertyName];

                if (range.location == NSNotFound) {

                    continue;

                } else {

                    id propertyValue = [dictionary objectForKey:propertyName];

                    

                    switch (rtype) {

                        case JsonToModelDataTypeBOOL:

                        {

                            BOOL temp = [[NSString stringWithFormat:@"%@",propertyValue] boolValue];

                            propertyValue = [NSNumber numberWithBool:temp];

                        }

                            break;

                        case JsonToModelDataTypeInteger:

                        {

                            int temp = [[NSString stringWithFormat:@"%@",propertyValue] intValue];

                            propertyValue = [NSNumber numberWithInt:temp];

                        }

                            break;

                        case JsonToModelDataTypeFloat:

                        {

                            float temp = [[NSString stringWithFormat:@"%@",propertyValue] floatValue];

                            propertyValue = [NSNumber numberWithFloat:temp];

                        }

                            break;

                        case JsonToModelDataTypeDouble:

                        {

                            double temp = [[NSString stringWithFormat:@"%@",propertyValue] doubleValue];

                            propertyValue = [NSNumber numberWithDouble:temp];

                        }

                            break;

                        case JsonToModelDataTypeLong:

                        {

                            long long temp = [[NSString stringWithFormat:@"%@",propertyValue] longLongValue];

                            propertyValue = [NSNumber numberWithLongLong:temp];

                        }

                            break;

                            

                        default:

                            break;

                    }

                    

                    [object setValue:propertyValue forKey:memberName];

                    

                    break;

                }

            }

        }

    }

    @catch (NSException *exception) {

        NSLog(@"%@",exception);

    }@finally {

        return object;

    }

}


注意:定义的属性名要与字典的关键字一样,否则生成的字典,那个关键字与属性名称不对的会变成<nil>




0 0
原创粉丝点击