用字典给Model赋值

此篇教程讲述通过runtime扩展NSObject,可以直接用字典给Model赋值,这是相当有用的技术呢。

源码:

NSObject+Properties.h 与 NSObject+Properties.m

  1. //
  2. // NSObject+Properties.h
  3. //
  4. // Created by YouXianMing on 14-9-4.
  5. // Copyright (c) 2014年 YouXianMing. All rights reserved.
  6. //
  7.  
  8. #import <Foundation/Foundation.h>
  9.  
  10. @interface NSObject (Properties)
  11.  
  12. - (void)setDataDictionary:(NSDictionary*)dataDictionary;
  13. - (NSDictionary *)dataDictionary;
  14.  
  15. @end
  1. //
  2. // NSObject+Properties.m
  3. //
  4. // Created by YouXianMing on 14-9-4.
  5. // Copyright (c) 2014年 YouXianMing. All rights reserved.
  6. //
  7.  
  8. #import "NSObject+Properties.h"
  9. #import <objc/runtime.h>
  10.  
  11. @implementation NSObject (Properties)
  12.  
  13. #pragma public - 公开方法
  14.  
  15. - (void)setDataDictionary:(NSDictionary*)dataDictionary
  16. {
  17. [self setAttributes:dataDictionary obj:self];
  18. }
  19.  
  20. - (NSDictionary *)dataDictionary
  21. {
  22. // 获取属性列表
  23. NSArray *properties = [self propertyNames:[self class]];
  24.  
  25. // 根据属性列表获取属性值
  26. return [self propertiesAndValuesDictionary:self properties:properties];
  27. }
  28.  
  29. #pragma private - 私有方法
  30.  
  31. // 通过属性名字拼凑setter方法
  32. - (SEL)getSetterSelWithAttibuteName:(NSString*)attributeName
  33. {
  34. NSString *capital = [[attributeName substringToIndex:] uppercaseString];
  35. NSString *setterSelStr = \
  36. [NSString stringWithFormat:@"set%@%@:", capital, [attributeName substringFromIndex:]];
  37. return NSSelectorFromString(setterSelStr);
  38. }
  39.  
  40. // 通过字典设置属性值
  41. - (void)setAttributes:(NSDictionary*)dataDic obj:(id)obj
  42. {
  43. // 获取所有的key值
  44. NSEnumerator *keyEnum = [dataDic keyEnumerator];
  45.  
  46. // 字典的key值(与Model的属性值一一对应)
  47. id attributeName = nil;
  48. while ((attributeName = [keyEnum nextObject]))
  49. {
  50. // 获取拼凑的setter方法
  51. SEL sel = [obj getSetterSelWithAttibuteName:attributeName];
  52.  
  53. // 验证setter方法是否能回应
  54. if ([obj respondsToSelector:sel])
  55. {
  56. id value = nil;
  57. id tmpValue = dataDic[attributeName];
  58.  
  59. if([tmpValue isKindOfClass:[NSNull class]])
  60. {
  61. // 如果是NSNull类型,则value值为空
  62. value = nil;
  63. }
  64. else
  65. {
  66. value = tmpValue;
  67. }
  68.  
  69. // 执行setter方法
  70. [obj performSelectorOnMainThread:sel
  71. withObject:value
  72. waitUntilDone:[NSThread isMainThread]];
  73. }
  74. }
  75. }
  76.  
  77. // 获取一个类的属性名字列表
  78. - (NSArray*)propertyNames:(Class)class
  79. {
  80. NSMutableArray *propertyNames = [[NSMutableArray alloc] init];
  81. unsigned int propertyCount = ;
  82. objc_property_t *properties = class_copyPropertyList(class, &propertyCount);
  83.  
  84. for (unsigned int i = ; i < propertyCount; ++i)
  85. {
  86. objc_property_t property = properties[i];
  87. const char *name = property_getName(property);
  88.  
  89. [propertyNames addObject:[NSString stringWithUTF8String:name]];
  90. }
  91.  
  92. free(properties);
  93.  
  94. return propertyNames;
  95. }
  96.  
  97. // 根据属性数组获取该属性的值
  98. - (NSDictionary*)propertiesAndValuesDictionary:(id)obj properties:(NSArray *)properties
  99. {
  100. NSMutableDictionary *propertiesValuesDic = [NSMutableDictionary dictionary];
  101.  
  102. for (NSString *property in properties)
  103. {
  104. SEL getSel = NSSelectorFromString(property);
  105.  
  106. if ([obj respondsToSelector:getSel])
  107. {
  108. NSMethodSignature *signature = nil;
  109. signature = [obj methodSignatureForSelector:getSel];
  110. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
  111. [invocation setTarget:obj];
  112. [invocation setSelector:getSel];
  113. NSObject * __unsafe_unretained valueObj = nil;
  114. [invocation invoke];
  115. [invocation getReturnValue:&valueObj];
  116.  
  117. //assign to @"" string
  118. if (valueObj == nil)
  119. {
  120. valueObj = @"";
  121. }
  122.  
  123. propertiesValuesDic[property] = valueObj;
  124. }
  125. }
  126.  
  127. return propertiesValuesDic;
  128. }
  129.  
  130. @end

测试用Model

Model.h 与 Model.m

  1. //
  2. // Model.h
  3. // Runtime
  4. //
  5. // Created by YouXianMing on 14-9-5.
  6. // Copyright (c) 2014年 YouXianMing. All rights reserved.
  7. //
  8.  
  9. #import <Foundation/Foundation.h>
  10.  
  11. @interface Model : NSObject
  12.  
  13. @property (nonatomic, strong) NSString *name;
  14. @property (nonatomic, strong) NSNumber *age;
  15. @property (nonatomic, strong) NSDictionary *addressInfo;
  16. @property (nonatomic, strong) NSArray *events;
  17.  
  18. @end
  1. //
  2. // Model.m
  3. // Runtime
  4. //
  5. // Created by YouXianMing on 14-9-5.
  6. // Copyright (c) 2014年 YouXianMing. All rights reserved.
  7. //
  8.  
  9. #import "Model.h"
  10.  
  11. @implementation Model
  12.  
  13. @end

使用时的情形

  1. //
  2. // AppDelegate.m
  3. // Runtime
  4. //
  5. // Created by YouXianMing on 14-9-5.
  6. // Copyright (c) 2014年 YouXianMing. All rights reserved.
  7. //
  8.  
  9. #import "AppDelegate.h"
  10. #import "NSObject+Properties.h"
  11. #import "Model.h"
  12.  
  13. @implementation AppDelegate
  14.  
  15. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  16. {
  17. // 初始化model
  18. Model *model = [Model new];
  19.  
  20. // 通过字典赋值
  21. model.dataDictionary = @{@"name" : @"YouXianMing",
  22. @"age" : @,
  23. @"addressInfo" : @{@"HuBei": @"WeiHan"},
  24. @"events" : @[@"One", @"Two", @"Three"]};
  25.  
  26. // 打印出属性值
  27. NSLog(@"%@", model.dataDictionary);
  28.  
  29. return YES;
  30. }
  31.  
  32. @end

打印的信息:

2014-09-05 21:03:54.840 Runtime[553:60b] {

    addressInfo =     {

        HuBei = WeiHan;

    };

    age = 26;

    events =     (

        One,

        Two,

        Three

    );

    name = YouXianMing;

}

以下是两段核心代码(符合单一职能):

用字典给Model赋值的更多相关文章

  1. 用字典给Model赋值并支持map键值替换

    用字典给Model赋值并支持map键值替换 这个是昨天教程的升级版本,支持键值的map替换. 源码如下: NSObject+Properties.h 与 NSObject+Properties.m / ...

  2. 字典的快速赋值 setValuesForKeysWithDictionary

    字典的快速赋值 setValuesForKeysWithDictionary ​ 前言 在学习解析数据的时候,我们经常是这么写的:PersonModel.h文件中    @property (nona ...

  3. iOS UI基础-4.1应用程序管理 字典转Model

    用模型取代字典 使用字典的坏处 一般情况下,设置数据和取出数据都使用“字符串类型的key”,编写这些key时,编辑器没有智能提示,需要手敲 dict[@"name"] = @&qu ...

  4. 将JSON字典转换为Model文件

    将JSON字典转换为Model文件 1. 一切尽在不言中 2. 源码 https://github.com/YouXianMing/CreateModelFromJson 3. 说明 如果你还在手动写 ...

  5. 字典和Model的互转

    LHModel的简单使用: LHModel是一个JSON转model,model转JSON的工具类. 使用很多runtime的API.调用简单,真正能用到的只有两个方法. Model* model = ...

  6. 【iOS开发】字典的快速赋值 setValuesForKeysWithDictionary

    前言 在学习解析数据的时候,我们经常是这么写的:PersonModel.h文件中 @property (nonatomic,copy)NSString *name; @property (nonato ...

  7. 总结day5 ---- ,字典的学习,增删改查,以及字典的嵌套, 赋值运算

    内容大纲: 一:字典的定义 二:字典的增加 >1:按照key增加,  无则增加,有则覆盖 >2:setdefault()  ,无则增加,有则不变 三:字典的删除 >1:pop()  ...

  8. 利用特性和反射给泛型Model赋值

    为了解决从数据库读取的表字段和自己建的viewModel字段名称不相符的问题 本人小白,初次将特性及反射应用到实例,写的不好的地方还请大家多多包涵 新建一个控制台应用程序命名为ReflectAndAt ...

  9. TDictionary字典 记录 的赋值。

    type TRen = record age: Integer; //把name定义成结构的属性. private Fname: string; procedure Setname(const Val ...

随机推荐

  1. Oracle数据库 中的基础的一些语法结构

    方括号里的内容为可选项 大括号是必填 1PL/SQL结构块 DECLARE /* * 声明部分——定义常量.变量.复杂数据类型.游标.用户自定义异常 */ BEGIN /* * 执行部分——PL/SQ ...

  2. google tensorflow bert代码分析

    参考网上博客阅读了bert的代码,记个笔记.代码是 bert_modeling.py 参考的博客地址: https://blog.csdn.net/weixin_39470744/article/de ...

  3. ARM的体系结构与编程系列博客——ARM体系变种

    ARM体系变种的简介 有人会很奇怪一件事情,ARM居然会变种,不会是基因突变了吧,呵呵,其实ARM变种通俗一点来讲呢,就是ARM突然具备了一种特定的功能!并非是基因突变哦!ARM是reboot好不好? ...

  4. [转] Hadoop管理员的十个最佳实践

    前言 接触Hadoop有两年的时间了,期间遇到很多的问题,既有经典的NameNode和JobTracker内存溢出故障,也有HDFS存储小文件问题,既有任务调度问题,也有MapReduce性能问题.遇 ...

  5. 设计模式学习--装饰者模式(Decorator Pattern)

    概念: 装饰者模式(Decorator Pattern): 动态地将功能添加到对象,相比生成子类更灵活,更富有弹性. 解决方案: 装饰者模式的重点是对象的类型,装饰者对象必须有着相同的接口,也也就是有 ...

  6. Java中使用json时java.lang.NoClassDefFoundError: net/sf/ezmorph/Morpher问题解决

    下面代码: public static void main(String[] args) { JSONObject obj = new JSONObject(); obj.put("msg& ...

  7. 啰里吧嗦式讲解java静态代理动态代理模式

    一.为啥写这个 文章写的比较啰嗦,有些东西可以不看,因为想看懂框架, 想了解SSH或者SSM框架的设计原理和设计思路, 又去重新看了一遍反射和注解, 然后看别人的博客说想要看懂框架得先看懂设计模式,于 ...

  8. SpringMVC配置式开发

    所谓配置式开发是指“处理器类是程序员手工定义,实现了特定接口的类,然后再在SpringMVC 配置文件中对该类进行显示的.明确的注册”的开发方式. 一.处理器映射器HandlerMapping Han ...

  9. MQ之如何做到消息幂等 (转 优秀)

    一.缘起 MQ消息必达,架构上有两个核心设计点: (1)消息落地 (2)消息超时.重传.确认 再次回顾消息总线核心架构,它由 发送端.服务端.固化存储.接收端 四大部分组成. 为保证消息的可达性,超时 ...

  10. 零基础学python习题 - Python必须知道的基础语法

    1. 以下变量命名不正确的是(D) A. foo = the_value B. foo = l_value C. foo = _value D. foo = value_& 2. 计算2的38 ...