使用Runtime的objc_msgSend实现模型和字典的互转
一、介绍
模型转字典,字典转模型,这是开发中最基本的功能。系统类中提供了一个setValuesForKeysWithDictionary方法来实现字典转模型,至于模型转字典,这个就需要使用runtime来实现了。其实字典和模型的互转可以完全使用运行时runtime来实现。典型的第三方有MJExtension和YYModel。现在我就来借助runtime的思想来进行大致的实现。
二、思路
- 字典转模型
- 遍历key
- objc_msgSend对key发送消息
- 模型转字典
- class_copyPropertyList获取属性列表properties
- 遍历properties,获取属性名name
- objc_msgSend对name发送消息,设置value
- 存入dic并返回
三、示例
person.h
//
// Person.h
// 运行时
//
// Created by 夏远全 on 2019/10/11.
// Copyright © 2019 北京华樾教育科技有限公司. All rights reserved.
// #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface Person : NSObject
@property (nonatomic, copy) NSString *age;
@property (nonatomic, copy) NSString *name; /**
字典转模型
@param dic 字典
@return 模型
*/
-(instancetype)initWithDictionary:(NSDictionary *)dic; /**
模型转字典
@return 字典
*/
-(NSDictionary *)convertModelToDictionary; @end NS_ASSUME_NONNULL_END
person.m
//
// Person.m
// 运行时
//
// Created by 夏远全 on 2019/10/11.
// Copyright © 2019 北京华樾教育科技有限公司. All rights reserved.
// #import "Person.h"
#import <objc/message.h> @implementation Person -(instancetype)initWithDictionary:(NSDictionary *)dic{ self = [super init];
if (self) {
for (NSString *key in dic.allKeys) {
//创建一个set选择器
NSString *methodName = [NSString stringWithFormat:@"set%@:",key.capitalizedString];
SEL selector = NSSelectorFromString(methodName); //类型异常处理
id value = dic[key];
if([value isKindOfClass:[NSNull class]]) continue; //发送消息
if (!selector) continue;
((void (*)(id, SEL, id))objc_msgSend)(self, selector, value);
}
}
return self;
} -(NSDictionary *)convertModelToDictionary { NSMutableDictionary *dic = [NSMutableDictionary dictionary]; unsigned int count;
objc_property_t *properties = class_copyPropertyList([self class], &count);
for (int i=; i<count; i++) {
objc_property_t property = properties[i]; //属性名称
const char * name = property_getName(property);
NSString *propertyName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding]; //创建一个get选择器
SEL selector = NSSelectorFromString(propertyName); //发送消息
if (!selector) continue;
id value = ((id (*)(id, SEL))objc_msgSend)(self, selector); //空与类型异常处理
if(!value || [value isKindOfClass:[NSNull class]]) continue; //值存储
[dic setValue:value forKey:propertyName];
} //copy创建的需要释放
free(properties); return dic;
} @end
四、测试
1、dic -> model
-(void)test_objc_DicToModel { /// 这里主要提供一个思想,全部用字符串作为字段。其他类型:对象类型/NSNumber/int/float...,需要自己再去特殊处理
NSDictionary *dic = @{@"age":@"",@"name":@"张三"};
Person *person = [[Person alloc] initWithDictionary:dic];
NSLog(@"age=%@,name=%@",person.age, person.name);
}
-- ::47.366662+ 运行时[:] age=,name=张三
2、model -> dic
-(void)test_objc_ModelToDic { NSDictionary *dic = @{@"age":@"",@"name":@"张三"};
Person *person = [[Person alloc] initWithDictionary:dic];
NSDictionary *dic2 = [person convertModelToDictionary];
NSLog(@"%@",dic2);
}
-- ::47.367024+ 运行时[:] {
age = ;
name = "\U5f20\U4e09";
}
使用Runtime的objc_msgSend实现模型和字典的互转的更多相关文章
- KVC简介 -字典转模型,模型转字典
// 下面两个方法.都属于 KVC 的方法 // KVC 是 cocoa 的大招.间接给对象属性设置数值 // 程序运行过程中,动态给对象属性设置数值.不关心 .h 中是怎样定义的 // 仅 ...
- 利用runTime,实现以模型为主的字典转模型(注意与KVC的区别)
将字典转化为模型,面向模型开发,是在开发中最为常用的功能.利用KVC可以将字典转换为模型,但是前提有三个约束,一个是必须保证模型的属性个数大于等于字典个数,二是属性名称与字典的key必须相同,三是对于 ...
- IOS中用模型取代字典的好处
使用字典的坏处 一般情况下,设置数据和取出数据都是用“字符串类型的key”,编写这些key时,编译器不会有任何友情提示,需要手敲 dict[@“name”]=@“Kevin”; NSString *n ...
- flask学习(十):模板中访问模型和字典的属性
访问模型中的属性或者是字典,可以通过{{params.property}}的形式,或者是使用{{params['age']}}这样的形式
- python字符串字典列表互转
#-*-coding:utf-8-*- #1.字典 dict = {'name': 'Zara', 'age': 7, 'class': 'First'} #字典转为字符串,返回:<type ' ...
- ios开发runtime学习五:KVC以及KVO,利用runtime实现字典转模型
一:KVC和KVO的学习 #import "StatusItem.h" /* 1:总结:KVC赋值:1:setValuesForKeysWithDictionary实现原理:遍历字 ...
- iOS 字典转模型Model
基本原理 利用 runtime 原理,获取模型中所有实例变量列表,根据实例变量以此获取模型中成员变量的名称和属性类型,区分Foundation和自定义属性,需要对NSDictionary和NSArra ...
- JsonString,字典,模型之间相互转换
NSData转字符串 [NSString alloc] initWithData: encoding:] 模型转字典 attInfo.keyValues 字典转模型 ZTEOutputInfo *ou ...
- iOS开发UI篇—字典转模型
iOS开发UI篇—字典转模型 一.能完成功能的“问题代码” 1.从plist中加载的数据 2.实现的代码 // // LFViewController.m // 03-应用管理 // // Creat ...
随机推荐
- [转载]——Full UNDO Tablespace In 10gR2 and above (文档 ID 413732.1)
最近遇到了这个案例,官方文档已有详尽的分析.介绍,特转载在此,方便以后查看! Full UNDO Tablespace In 10gR2 and above (SQL> select count ...
- 表单生成器(Form Builder)之伪造表单数据mongodb篇
这篇文章终于回到了正轨:为mongodb伪造数据.之前的随机数.随机车牌照.随机时间还有这篇笔记中的获取指定长度的中文字符串,都是为这篇笔记做准备.看一下我们的准备(基础代码) // 1.获取指定范围 ...
- subprocess之check_out用法
在python3中使用subprocess的check_out方法时,因为该输出为byte类型,所以如果要查看具体的内容时需要进行转码,如果转码不对话,会影响内容输出的可读性,如下: #1,输出解码不 ...
- pytest系列(四)- pytest+allure+jenkins - 持续集成平台生成allure报告
pytest是什么 pytest是python的一款测试框架,拥有unittest的功能并比它更丰富. allure是什么 有非常多的优秀的测试框架,但却是有非常少优秀的报告工具可以展示非常清楚的用例 ...
- ubuntu18.04因java路径原因启动jenkins失败
我的云服务器ubuntu18.04上本来装了jenkins,今天安装完tomcat后,将原有的openjdk卸载了,安装了jdk8u192, 此时浏览器访问8080端口显示的就是tomcat安装成功的 ...
- 在CV尤其是CNN领域的一些想法
现在的CNN还差很多,未来满是变数. 你看,现在的应用领域也无非merely就这么几类----分类识别,目标检测(定位+识别),对象分割......,但是人的视觉可不仅仅这么几个功能啊!是吧. 先说说 ...
- PHP如何开启swoole扩展
swoole是一个PHP的异步.并行.高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接池,AsyncT ...
- Java题库——Chapter8 对象和类
1)________ represents an entity(实体) in the real world that can be distinctly identified. 1) _______ ...
- (转)Python- sklearn之最小二乘法
最小二乘法:https://baike.baidu.com/item/%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%98%E6%B3%95/2522346?fr=aladdin ...
- 设计好的报表是如何在 web 上显示的
润乾报表主要用来开发在 java web 端呈现的报表工具,设计器为桌面版,那么开发后的报表如何发布到 web 端是用户较为关心的问题. 润乾报表 web 端发布,采用 Taglib 方式,只需要在 ...