將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];
}

這時我發(fā)現上面的代碼只能轉化簡單的model, 而value的可能情況很多,可能是數組,可能是字典,一會又發(fā)現數組或字典里可能嵌套數組或字典或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的代碼,思路應該跟這個是類似的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • iOS網絡架構討論梳理整理中。。。 其實如果沒有APIManager這一層是沒法使用delegate的,畢竟多個單...
    yhtang閱讀 5,491評論 1 23
  • 引導 對于從事 iOS 開發(fā)人員來說,所有的人都會答出「 Runtime 是運行時 」,什么情況下用 Runtim...
    Winny_園球閱讀 397評論 0 0
  • runtime 常見作用 該文件的目的是為讀者誰可能有興趣學習的Objective-C的運行時。因為這不是一個關于...
    陽明AI閱讀 1,000評論 1 13
  • 什么是runtime? runtime 是 OC底層的一套C語言的API(引入 <objc/runtime.h>或...
    木子奕閱讀 1,688評論 0 16
  • 夕陽還有半張臉 我與預先約好的朋友 走進了董小姐咖啡廳 墻面上印滿向日葵 地上是巨型羅馬字 我不喜歡咖啡 也痛恨小...
    向日葵愛呀愛太陽閱讀 525評論 0 1

友情鏈接更多精彩內容