美文网首页
iOS Model模型转换三方调研

iOS Model模型转换三方调研

作者: spades_K | 来源:发表于2018-04-19 16:29 被阅读96次

    传统的KVC实现模型转换

    定义一个User类
    @interface User : NSObject
    @property(copy,nonatomic) NSString *name;
    @property(copy,nonatomic) NSString *gender;
    @property(copy,nonatomic) NSString *age;
    @property(copy,nonatomic) NSString *userId;
    @property(copy,nonatomic) NSMutableArray *roles;
    @end
    
    耗时计算
    //
    //  ViewController.m
    //  ModelConversionContrast
    //
    //  Created by rck on 2018/4/19.
    //  Copyright © 2018年 RCK. All rights reserved.
    //
    
    #import "ViewController.h"
    #import "Models.h"
    #import <MJExtension.h>
    #import <YYModel.h>
    @interface ViewController ()
    @property(strong,nonatomic)NSDictionary *userDict;
    @end
    
    // 测试次数
    static int testCout = 10;
    // 转换次数
    static int contrastCout = 10000;
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // KVC耗时(性能最佳 后面就不比对多model嵌套问题了)。
        [self kvcModelContrast];
        
        
        // MJExtension 耗时
        [self mjextensionContrast];
        
        // YYModel耗时
        [self yyModelContrast];
        
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    
    #pragma mark - KVC
    - (void)kvcModelContrast
    {
        // 定义模型字典
        
        double allTime = 0;
        
        for (int i = 0; i <testCout; i++) {
            // 毫秒
            double stDate = [[NSDate date] timeIntervalSince1970] *1000;
            for (int i = 0; i <contrastCout; i++) {
                User *user = [[User alloc] init];
                [user setValuesForKeysWithDictionary:self.userDict];
            }
            
            // 毫秒
            double edDate = [[NSDate date] timeIntervalSince1970] *1000;
            
            //        NSLog(@"耗时-----%f毫秒",edDate-stDate);
            allTime += (edDate-stDate);
        }
        
        NSLog(@"KVC 单层模型转换 方法执行%d次 循环转换%d次,平均耗时%f毫秒",testCout,contrastCout,allTime/testCout);
    
    }
    
    
    
    #pragma mark - 三方获取属性方法
    - (void)getAllPropertys
    {
        unsigned int propertyCount = 0;
        ///通过运行时获取当前类的属性
        objc_property_t *propertys = class_copyPropertyList([User class], &propertyCount);
        
        //把属性放到数组中
        for (int i = 0; i < propertyCount; i ++) {
            ///取出第一个属性
            objc_property_t property = propertys[i];
            //得到属性对应的名称
            NSString *name = @(property_getName(property));
            
            NSLog(@"name:%@", name);
        }
        
    }
    
    
    #pragma mark - MJEXtension
    - (void)mjextensionContrast
    {
        // 定义模型字典
        double allTime = 0;
        
        for (int i = 0; i <testCout; i++) {
            // 毫秒
            double stDate = [[NSDate date] timeIntervalSince1970] *1000;
            for (int i = 0; i <contrastCout; i++) {
                User *user = [[User alloc] init];
                [user mj_setKeyValues:self.userDict];
                
                
    //             NSLog(@"替换的 id  属性%@ 容器model容器 %@",user.userId,user.roles); // 替换的 id  属性1
            }
            
            // 毫秒
            double edDate = [[NSDate date] timeIntervalSince1970] *1000;
            
            //        NSLog(@"耗时-----%f毫秒",edDate-stDate);
            allTime += (edDate-stDate);
        }
        
        NSLog(@"MJEXtension %@层模型转换 执行%d次 循环转换%d次,平均耗时%f毫秒",self.userDict[@"roles"]?@"多":@"单", testCout,contrastCout,allTime/testCout);
    
    }
    
    
    
    #pragma mark YYModel
    - (void)yyModelContrast
    {
        // 定义模型字典
        double allTime = 0;
        
        for (int i = 0; i <testCout; i++) {
            // 毫秒
            double stDate = [[NSDate date] timeIntervalSince1970] *1000;
            for (int i = 0; i <contrastCout; i++) {
                User *user = [User yy_modelWithJSON:self.userDict];
                
    //            NSLog(@"替换的 id  属性%@ 容器model容器 %@",user.userId,user.roles); // 替换的 id  属性1
            }
            
            // 毫秒
            double edDate = [[NSDate date] timeIntervalSince1970] *1000;
            
            //        NSLog(@"耗时-----%f毫秒",edDate-stDate);
            allTime += (edDate-stDate);
        }
        
        NSLog(@"YYModel %@层模型转换 执行%d次 循环转换%d次,平均耗时%f毫秒",self.userDict[@"roles"]?@"多":@"单", testCout,contrastCout,allTime/testCout);
    
    }
    
    
    #pragma mark - SetterAndGetters
    - (NSDictionary *)userDict
    {
        return @{@"name":@"Jack",
                 @"gender":@"man",
                 @"age":@"18",
                 @"id":@"1"
                 /* 注释下面则为单层model*/
                 ,@"roles":@[@{@"name":@"staff"},
                            @{@"name":@"citizen"}]
                 };
    }
    
    
    @end
    
    优点:
    • 单层Model一句话转换,简洁方便。
    缺点:
    • 实际使用中需定义 setValue:forUndefinedKey:方法不然容易崩溃。
    • 遇到model嵌套情况代码量增大,需要循环创建处理。
    • 对数据的容错率低,需要判断后台返回数据是否符合,出现null数据可能导致程序崩溃。
    三方框架的优点
    • 它的兼容性好,拓展性强,使代码更健壮。
    • 很大程度的缩减代码量。
    • 转化效率?
    时效对比 KVC与MJExtension单层model转换
    2018-04-19 15:26:49.905309+0800[2065:491747] KVC 单层模型转换 方法执行10次 循环转换10000次,平均耗时24.895508毫秒
    2018-04-19 15:26:52.922414+0800[2065:491747] MJEXtension 单层模型转换 执行10次 循环转换10000次,平均耗时301.692432毫秒
    
    

    介绍几个主流的iOS转换Model框架

    1.MJExtension

    MJExtension.png 161d2039c2a5a948.png
    代码详解见这里✋
    使用方法 全中文注释
    引入工程:21个文件80K 量级较大 功能也支持很多比如支持CoreData plist 与Model的转话等。类目较多,如果只是简单的转换 不推荐引入。
    常用方法
    /**
    @implementation User
    
     key值替换
    
     @return @{需要的值:替换的值}
     */
    + (NSDictionary *)mj_replacedKeyFromPropertyName
    {
        return @{@"userId":@"id"// key对应数组,数组里面为模型
                 };
    }
    
    
    /**
     model嵌套问题
    
     @return @{接受的key值:[需要嵌套在内的类 class]};
     */
    + (NSDictionary *)mj_objectClassInArray
    {
        return @{@"roles":[Role class]};
    }
    @end
    

    YYModel

    YYModel.png
    代码详解见这里✋1 代码详解见这里✋2
    使用方法见这里✋
    引入工程:5个文件 120k。
    先看下转化效率对比
    • 多层模型
    2018-04-19 16:11:35.197779+0800 ModelConversionContrast[2085:498926] MJEXtension 多层模型转换 执行10次 循环转换10000次,平均耗时822.410645毫秒
    2018-04-19 16:11:36.473886+0800 ModelConversionContrast[2085:498926] YYModel 多层模型转换 执行10次 循环转换10000次,平均耗时127.587207毫秒
    
    
    • 单层模型
    2018-04-19 16:13:25.193517+0800 ModelConversionContrast[2088:499480] KVC 单层模型转换 方法执行10次 循环转换10000次,平均耗时24.614404毫秒
    2018-04-19 16:13:28.180702+0800 ModelConversionContrast[2088:499480] MJEXtension 单层模型转换 执行10次 循环转换10000次,平均耗时298.698267毫秒
    2018-04-19 16:13:28.680770+0800 ModelConversionContrast[2088:499480] YYModel 单层模型转换 执行10次 循环转换10000次,平均耗时49.986694毫秒
    
    
    常用方法
    @implementation User
    
    #pragma mark -YYModel
    /**
     key值替换问题
     @return  @{接受的key值:[需要嵌套在内的类 class]};
     */
    + (NSDictionary *)modelCustomPropertyMapper {
        return @{@"userId":@"id"};
        
        // 例子 bookID  支持 多个替换值
    //    + (NSDictionary *)modelCustomPropertyMapper {
    //        return @{@"name"  : @"n",
    //                 @"page"  : @"p",
    //                 @"desc"  : @"ext.desc",
    //                 @"bookID": @[@"id", @"ID", @"book_id"]};
    //    }
    }
    
    
    /**
     model替换
    
     @return 返回容器类中的所需要存放的数据类型 (以 Class 或 Class Name 的形式)。
    
     */
    + (NSDictionary *)modelContainerPropertyGenericClass {
        return @{@"roles":[Role class]};
        
    //    return @{@"roles":@"Role"};
    
    }
    
    @end
    
    

    相关文章

      网友评论

          本文标题:iOS Model模型转换三方调研

          本文链接:https://www.haomeiwen.com/subject/zkzikftx.html