使用RunTime實(shí)現(xiàn)字典轉(zhuǎn)模型

具體實(shí)現(xiàn)代碼請看GItHub如果覺得不錯,請start一下,謝謝!

1.如何快速生成Plist文件屬性名

  • 實(shí)現(xiàn)原理:通過遍歷字典,判斷類型,拼接字符串
    // 拼接屬性字符串代碼
    NSMutableString *strM = [NSMutableString string];
    
    // 1.遍歷字典,把字典中的所有key取出來,生成對應(yīng)的屬性代碼
    [dict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        
    NSString *type;
        
        if ([obj isKindOfClass:NSClassFromString(@"__NSCFString")]) {
            type = @"NSString";
        }else if ([obj isKindOfClass:NSClassFromString(@"__NSCFArray")]){
            type = @"NSArray";
        }else if ([obj isKindOfClass:NSClassFromString(@"__NSCFNumber")]){
            type = @"int";
        }else if ([obj isKindOfClass:NSClassFromString(@"__NSCFDictionary")]){
            type = @"NSDictionary";
        }else if ([obj isKindOfClass:NSClassFromString(@"__NSCFBoolean")]){
            type = @"BooL";
        }
        // 屬性字符串
        NSString *str;
        if ([type containsString:@"NS"]) {
            str = [NSString stringWithFormat:@"@property (nonatomic, strong) %@ *%@;",type,key];
        }else{
            str = [NSString stringWithFormat:@"@property (nonatomic, assign) %@ %@;",type,key];
        }
        // 每生成屬性字符串,就自動換行。
        [strM appendFormat:@"\n%@\n",str];  
    }];
    // 把拼接好的字符串打印出來,就好了。
    NSLog(@"%@",strM);

打印結(jié)果

2.KVC實(shí)現(xiàn)字典轉(zhuǎn)模型

  • KVC弊端
    • 模型中屬性必須和字典的key一致,否則就報(bào)錯
    • 如果不一致,系統(tǒng)會調(diào)用setValue: forUndefinedKey:
    • 解決辦法,只需要重寫setValue: forUndefinedKey:即可
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{

}

3.RunTime實(shí)現(xiàn)字典轉(zhuǎn)模型

  • 實(shí)現(xiàn)思路:遍歷模型中所有屬性,根據(jù)模型的屬性名去字典中查找key,取出對應(yīng)的的值,給模型的屬性賦值

一級轉(zhuǎn)換
class_copyIvarList(self, &count)該方法第一個參數(shù)是要獲取哪個類中的成員屬性,第二個參數(shù)是這個類中有多少成員屬性,需要傳入地址,返回值Ivar是個數(shù)組,會將所有成員屬性放入這個數(shù)組中

    id objc = [[self alloc] init];
    
    unsigned int count;
    
    // 獲取類中的所有成員屬性
    Ivar *ivarList = class_copyIvarList(self, &count);
    
    for (int i = 0; i < count; i++) {
        Ivar ivar = ivarList[i];
        
        // 獲取成員屬性名
        NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];
        
        // 處理成員屬性名->字典中的key
        // 從第一個角標(biāo)開始截取
        NSString *key = [name substringFromIndex:1];
        
        // 根據(jù)成員屬性名去字典中查找對應(yīng)的value
        id value = dict[key];

二級轉(zhuǎn)換
判斷字典中是否存在字典,如果存在,轉(zhuǎn)為模型
字典屬性生成的是@"@\"xxxx\""類型,需要裁減為@"xxxx"

    if ([value isKindOfClass:[NSDictionary class]]) {
            // 獲取成員屬性類型
            NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
            // 生成的是這種@"@\"User\"" 類型 -》 @"User"  在OC字符串中 \" -> ",\是轉(zhuǎn)義的意思,不占用字符
            // 裁剪類型字符串
            NSRange range = [type rangeOfString:@"\""];
            
            type = [type substringFromIndex:range.location + range.length];
            range = [type rangeOfString:@"\""];
            // 裁剪到哪個角標(biāo),不包括當(dāng)前角標(biāo)
            type = [type substringToIndex:range.location];
            // 根據(jù)字符串類名生成類對象
            Class modelClass = NSClassFromString(type); 
            if (modelClass) {
                value  =  [modelClass modelWithDict:value];
            }
        }

三級轉(zhuǎn)換
通過給分類添加一個協(xié)議,來實(shí)現(xiàn)將數(shù)組中的字典轉(zhuǎn)為模型

        if ([value isKindOfClass:[NSArray class]])
        {
            // 判斷對應(yīng)類有沒有實(shí)現(xiàn)字典數(shù)組轉(zhuǎn)模型數(shù)組的協(xié)議
            if ([self respondsToSelector:@selector(arrayContainModelClass)]) {
                
                // 轉(zhuǎn)換成id類型,就能調(diào)用任何對象的方法
                id idSelf = self;
                // 獲取數(shù)組中字典對應(yīng)的模型
                NSString *type =  [idSelf arrayContainModelClass][key];
                // 生成模型
                Class classModel = NSClassFromString(type);
                NSMutableArray *arrM = [NSMutableArray array];
                // 遍歷字典數(shù)組,生成模型數(shù)組
                for (NSDictionary *dict in value) {
                    // 字典轉(zhuǎn)模型
                    id model =  [classModel modelWithDict:dict];
                    [arrM addObject:model];
                }
                // 把模型數(shù)組賦值給value
                value = arrM;
            }
        }

還在學(xué)習(xí)中,略有錯誤請大家指出,謝謝!

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

相關(guān)閱讀更多精彩內(nèi)容

  • 一 快速生成@property 1 當(dāng)我們需要用模型去實(shí)現(xiàn)一個比較小的功能的時(shí)候,由于我們需要對plist文件進(jìn)行...
    莫許閱讀 707評論 1 1
  • 對于從事 iOS 開發(fā)人員來說,所有的人都會答出【runtime 是運(yùn)行時(shí)】什么情況下用runtime?大部分人能...
    夢夜繁星閱讀 3,799評論 7 64
  • 一、runtime簡介 RunTime簡稱運(yùn)行時(shí)。OC就是運(yùn)行時(shí)機(jī)制,也就是在運(yùn)行時(shí)候的一些機(jī)制,其中最主要的是消...
    Lucky丶晴閱讀 2,229評論 1 2
  • 我自己是屬于不怎么長痘痘的類型,但是熬夜上火就會爆很大的痘痘,換季長得比較頻繁,就是又紅又腫又疼的那種,經(jīng)常出現(xiàn)在...
    ccm123閱讀 2,540評論 0 1
  • 寒風(fēng)掃蕩原野深處 土地消瘦,變了模樣 天空也被清掃得空空蕩蕩 月兒像一只孤魂在流浪 莊稼歸了倉房 牛羊回了圈場 父...
    心海安瀾閱讀 328評論 2 14

友情鏈接更多精彩內(nèi)容