zoukankan      html  css  js  c++  java
  • 利用runTime,实现以模型为主的字典转模型(注意与KVC的区别)

      将字典转化为模型,面向模型开发,是在开发中最为常用的功能。利用KVC可以将字典转换为模型,但是前提有三个约束,一个是必须保证模型的属性个数大于等于字典个数,二是属性名称与字典的key必须相同,三是对于模型中的基本数据类型无法转换。

      其中第一条与第三条,是其最大的弊端。例如,如果从服务器获取的数据字典,并不想使用所有的键值对。但是在开发中还是必须得全部将对应属性列出,全部进行转换(除非你一个一个写,不使用KVC)。

      下面的代码就可以解决上述问题:实现以模型为主,将字典数据进行部分转化,并识别基本数据类型。约束仅仅是要求模型属性名称与字典KEY保持一致(因为底层还是使用KVC);

     1 //
     2 //  NSObject+Value.m
     3 //
     4 //  Created by shunzi 5-10-2014.
     5 //  Copyright (c) 2014年 shunzi. All rights reserved.
     6 //
     7 
     8 #import "NSObject+Value.h"
     9 #import <objc/message.h>
    10 #import <objc/runtime.h>
    11 
    12 @implementation NSObject (Value)
    13 - (void)setValues:(NSDictionary *)values
    14 {
    15     Class c = [self class];
    16     
    17     while (c) {
    18         // 1.获得所有的成员变量
    19         unsigned int outCount = 0;
    20         Ivar *ivars = class_copyIvarList(c, &outCount);
    21 
    22         for (int i = 0; i<outCount; i++) {
    23             Ivar ivar = ivars[i];
    24             
    25             // 2.属性名
    26             NSMutableString *name = [NSMutableString stringWithUTF8String:ivar_getName(ivar)];
    27             
    28             // 删除最前面的_
    29             [name replaceCharactersInRange:NSMakeRange(0, 1) withString:@""];
    30             
    31             // 3.取出属性值
    32             NSString *key = name;
    33             if ([key isEqualToString:@"desc"]) {
    34                 key = @"description";
    35             }
    36             if ([key isEqualToString:@"ID"]) {
    37                 key = @"id";
    38             }
    39             id value = values[key];
    40             if (!value) continue;
    41             
    42             // 4.SEL
    43             // 首字母
    44             NSString *cap = [name substringToIndex:1];
    45             // 变大写
    46             cap = cap.uppercaseString;
    47             // 将大写字母调换掉原首字母
    48             [name replaceCharactersInRange:NSMakeRange(0, 1) withString:cap];
    49             // 拼接set
    50             [name insertString:@"set" atIndex:0];
    51             // 拼接冒号:
    52             [name appendString:@":"];
    53             SEL selector = NSSelectorFromString(name);
    54             
    55             // 5.属性类型
    56             NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
    57             
    58             if ([type hasPrefix:@"@"]) { // 对象类型
    59                 objc_msgSend(self, selector, value);
    60             } else  { // 非对象类型
    61                 if ([type isEqualToString:@"d"]) {
    62                     objc_msgSend(self, selector, [value doubleValue]);
    63                 } else if ([type isEqualToString:@"f"]) {
    64                     objc_msgSend(self, selector, [value floatValue]);
    65                 } else if ([type isEqualToString:@"i"]) { 
    66                     objc_msgSend(self, selector, [value intValue]);
    67                 }  else { 
    68                     objc_msgSend(self, selector, [value longLongValue]);
    69                 }
    70             }
    71         }
    72         
    73         c = class_getSuperclass(c);
    74     }
    75 }
    76 @end

     头文件仅仅包含对此方法的声明,所以不在此粘贴

  • 相关阅读:
    帝国 标签模板 使用程序代码 去除html标记 并 截取字符串
    iis6 伪静态 iis配置方法 【图解】
    您来自的链接不存在 帝国CMS
    帝国cms Warning: Cannot modify header information headers already sent by...错误【解决方法】
    .fr域名注册 51元注册.fr域名
    帝国网站管理系统 恢复栏目目录 建立目录不成功!请检查目录权限 Godaddy Windows 主机
    星外虚拟主机管理平台 开通数据库 出现Microsoft OLE DB Provider for SQL Server 错误 '8004' 从字符串向 datetime 转换失败
    ASP.NET 自定义控件学习研究
    CSS层叠样式表之CSS解析机制的优先级
    ASP.NET程序员工作面试网络收藏夹
  • 原文地址:https://www.cnblogs.com/dashunzi/p/3741656.html
Copyright © 2011-2022 走看看