将model转化为字典

来源:互联网 发布:sql数据库存储过程 编辑:程序博客网 时间:2024/05/17 00:07

将model转化为字典

刚入行时就见过项目里有mode转化为字典的代码,后来用过MJExtension的第三方库,非常好用,其实原理就是利用runtime遍历所有属性值,然后进行转化。但是自己从来没有动手写过~~~今天亲自写一写

1.先用runtime遍历所有属性值

代码如下:

- (NSDictionary *)dicFromObject:(NSObject *)object {    NSMutableDictionary *dic = [NSMutableDictionary dictionary];    unsigned int count;    objc_property_t *propertyList = class_copyPropertyList([object class], &count);    for (int i = 0; i < count; i++) {        objc_property_t property = propertyList[i];        const char *cName = property_getName(property);        NSString *name = [NSString stringWithUTF8String:cName];        NSObject *value = [object valueForKey:name];//valueForKey返回的数字和字符串都是对象        if (value == nil) {            //null            //[dic setObject:[NSNull null] forKey:name];//这行可以注释掉?????        } else {            //model            [dic setObject:[self dicFromObject:value] forKey:name];        }    }    return [dic copy];}

这时我发现上面的代码只能转化简单的model, 而value的可能情况很多,可能是数组,可能是字典,一会又发现数组或字典里可能嵌套数组或字典或model,我的妈妈,单纯一个递归方法根本无法实现所有的情况,还需要再添加方法。这么太复杂吗?我记得别人写时很简单呀。于是我百度了一下,几乎所有代码都是上述类似代码,我也是醉了。。这根本无法适用在实际的项目里。

2.代码改进如下:

//model转化为字典- (NSDictionary *)dicFromObject:(NSObject *)object {    NSMutableDictionary *dic = [NSMutableDictionary dictionary];    unsigned int count;    objc_property_t *propertyList = class_copyPropertyList([object class], &count);    for (int i = 0; i < count; i++) {        objc_property_t property = propertyList[i];        const char *cName = property_getName(property);        NSString *name = [NSString stringWithUTF8String:cName];        NSObject *value = [object valueForKey:name];//valueForKey返回的数字和字符串都是对象        if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) {            //string , bool, int ,NSinteger            [dic setObject:value forKey:name];        } else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) {            //字典或字典            [dic setObject:[self arrayOrDicWithObject:(NSArray*)value] forKey:name];        } else if (value == nil) {            //null            //[dic setObject:[NSNull null] forKey:name];//这行可以注释掉?????        } else {            //model            [dic setObject:[self dicFromObject:value] forKey:name];        }    }    return [dic copy];}

需要单独处理字典或数组
代码如下:

//将可能存在model数组转化为普通数组- (id)arrayOrDicWithObject:(id)origin {    if ([origin isKindOfClass:[NSArray class]]) {        //数组        NSMutableArray *array = [NSMutableArray array];        for (NSObject *object in origin) {            if ([object isKindOfClass:[NSString class]] || [object isKindOfClass:[NSNumber class]]) {                //string , bool, int ,NSinteger                [array addObject:object];            } else if ([object isKindOfClass:[NSArray class]] || [object isKindOfClass:[NSDictionary class]]) {                //数组或字典                [array addObject:[self arrayOrDicWithObject:(NSArray *)object]];            } else {                //model                [array addObject:[self dicFromObject:object]];            }        }        return [array copy];    } else if ([origin isKindOfClass:[NSDictionary class]]) {        //字典        NSDictionary *originDic = (NSDictionary *)origin;        NSMutableDictionary *dic = [NSMutableDictionary dictionary];        for (NSString *key in originDic.allKeys) {            id object = [originDic objectForKey:key];            if ([object isKindOfClass:[NSString class]] || [object isKindOfClass:[NSNumber class]]) {                //string , bool, int ,NSinteger                [dic setObject:object forKey:key];            } else if ([object isKindOfClass:[NSArray class]] || [object isKindOfClass:[NSDictionary class]]) {                //数组或字典                [dic setObject:[self arrayOrDicWithObject:object] forKey:key];            } else {                //model                [dic setObject:[self dicFromObject:object] forKey:key];            }        }        return [dic copy];    }    return [NSNull null];}

代码编码完毕,我写了两个类Foo,Moo做测试:
Foo.h如下:

@interface Foo : NSObject@property(nonatomic, assign) int pwd;@property(nonatomic, strong) NSString *userName;@property(nonatomic, assign) BOOL isUrl;@property(nonatomic, strong) Moo *moo;@property(nonatomic, strong) NSArray *emailList;@property(nonatomic, strong) NSArray *manyMoo;@property(nonatomic, strong) NSDictionary *childrenList;@property(nonatomic, strong) NSDictionary *MooDic;@end

Moo.h如下:

@interface Moo : NSObject@property(nonatomic, strong) NSString *name;@property(nonatomic, strong) NSString *pwd;@property(nonatomic, strong) NSString *profile;@end

测试代码如下:

    Foo *foo = [[Foo alloc] init];    foo.userName = @"gaoyuqiang";    foo.userName = nil;    foo.pwd = 1234;    foo.isUrl = YES;    foo.emailList = @[@"sfa@234.com", @"2@34.com"];    Moo *moo = [[Moo alloc] init];    moo.name = @"moo";    moo.pwd = @"234";    moo.profile = @"mooooo";    foo.moo = moo;    Moo *moo1 = [[Moo alloc] init];    moo1.name = @"moo1";    moo1.pwd = @"234";    moo1.profile = @"mooooo";    Moo *moo2 = [[Moo alloc] init];    moo2.name = @"moo2";    moo2.pwd = @"234";    moo2.profile = @"mooooo";    foo.manyMoo = @[moo1, moo2];    foo.childrenList = @{@"name":@"gao", @"pwd":@"32424"};    foo.MooDic = @{@"1" : @{@"s1" : moo1, @"s2" : moo2, @"s3" : @[@"1", @"2"]}, @"2" : moo2};    NSDictionary *result = [self dicFromObject:foo];    NSLog(@"result=%@", result);

Log如下,无论如何嵌套都可以完全转化

2017-07-26 16:57:10.030 Testff[61302:2256815] result={    MooDic =     {        1 =         {            s1 =             {                name = moo1;                profile = mooooo;                pwd = 234;            };            s2 =             {                name = moo2;                profile = mooooo;                pwd = 234;            };            s3 =             (                1,                2            );        };        2 =         {            name = moo2;            profile = mooooo;            pwd = 234;        };    };    childrenList =     {        name = gao;        pwd = 32424;    };    emailList =     (        "sfa@234.com",        "2@34.com"    );    isUrl = 1;    manyMoo =     (                {            name = moo1;            profile = mooooo;            pwd = 234;        },                {            name = moo2;            profile = mooooo;            pwd = 234;        }    );    moo =     {        name = moo;        profile = mooooo;        pwd = 234;    };    pwd = 1234;}

有时间再写一个字典转model的代码,思路应该跟这个是类似的。