使用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 ...
随机推荐
- color颜色大全
- jenkins实现git自动拉取代码时替换配置文件
jenkins实现从git上自动拉取源代码——>自动编译——>发布到测试服务器——>验证测试,这个大家应该都知道,但是关于源代码里的配置文件,可能就会有点头疼了, 一般测试都会自己的 ...
- ubuntu18.04因java路径原因启动jenkins失败
我的云服务器ubuntu18.04上本来装了jenkins,今天安装完tomcat后,将原有的openjdk卸载了,安装了jdk8u192, 此时浏览器访问8080端口显示的就是tomcat安装成功的 ...
- Java学习笔记之面向对象、static关键字
一周Java学习总结 今天就总结理清一下关于面向对象和面向过程的程序设计的一些不同特点,以及讲下static关键字. 面向对象 现在接触的Java是面向对象的,现在的程序开发几乎都是以面向对象为基础的 ...
- Java 并发编程 | 线程池详解
原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...
- slave_master_info和slave_relay_log_info中的Master_log_pos不一致
最近在研究mysql的主从,发现一个问题,我在主库做任何修改时,在从库中只有slave_relay_log_info中的Master_log_pos在变化,而slave_master_info中的Ma ...
- Concepts & Implementation of PLs
http://perugini.cps.udayton.edu/teaching/courses/Spring2015/cps352/index.html#lecturenotes Programmi ...
- spring = servlet + 依赖管理 + 业务逻辑
spring = servlet + 依赖管理 + 业务逻辑
- ASP.NET Core 3.0 gRPC 配置使用HTTP
前言 gRPC是基于http/2,是同时支持https和http协议的,我们在gRPC实际使用中,在内网通讯场景下,更多的是走http协议,达到更高的效率,下面介绍如何在 .NET Core 3.0 ...
- 基于STM32F429,Cubemx的SDHC卡的基本Fatfs文件移植
本博文要求各位初步了解Fatfs文件系统 友情提示Fatfs官网:http://elm-chan.org/fsw/ff/00index_e.html 1.开发软件 keil5,Cube5.21 2.实 ...