一、介绍

模型转字典,字典转模型,这是开发中最基本的功能。系统类中提供了一个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实现模型和字典的互转的更多相关文章

  1. KVC简介 -字典转模型,模型转字典

    // 下面两个方法.都属于 KVC 的方法 // KVC 是 cocoa 的大招.间接给对象属性设置数值 // 程序运行过程中,动态给对象属性设置数值.不关心 .h 中是怎样定义的 //      仅 ...

  2. 利用runTime,实现以模型为主的字典转模型(注意与KVC的区别)

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

  3. IOS中用模型取代字典的好处

    使用字典的坏处 一般情况下,设置数据和取出数据都是用“字符串类型的key”,编写这些key时,编译器不会有任何友情提示,需要手敲 dict[@“name”]=@“Kevin”; NSString *n ...

  4. flask学习(十):模板中访问模型和字典的属性

    访问模型中的属性或者是字典,可以通过{{params.property}}的形式,或者是使用{{params['age']}}这样的形式

  5. python字符串字典列表互转

    #-*-coding:utf-8-*- #1.字典 dict = {'name': 'Zara', 'age': 7, 'class': 'First'} #字典转为字符串,返回:<type ' ...

  6. ios开发runtime学习五:KVC以及KVO,利用runtime实现字典转模型

    一:KVC和KVO的学习 #import "StatusItem.h" /* 1:总结:KVC赋值:1:setValuesForKeysWithDictionary实现原理:遍历字 ...

  7. iOS 字典转模型Model

    基本原理 利用 runtime 原理,获取模型中所有实例变量列表,根据实例变量以此获取模型中成员变量的名称和属性类型,区分Foundation和自定义属性,需要对NSDictionary和NSArra ...

  8. JsonString,字典,模型之间相互转换

    NSData转字符串 [NSString alloc] initWithData: encoding:] 模型转字典 attInfo.keyValues 字典转模型 ZTEOutputInfo *ou ...

  9. iOS开发UI篇—字典转模型

    iOS开发UI篇—字典转模型 一.能完成功能的“问题代码” 1.从plist中加载的数据 2.实现的代码 // // LFViewController.m // 03-应用管理 // // Creat ...

随机推荐

  1. Python3操作MySQL基于PyMySQL封装的类

    Python3操作MySQL基于PyMySQL封装的类   在未使用操作数据库的框架开发项目的时候,我们需要自己处理数据库连接问题,今天在做一个Python的演示项目,写一个操作MySQL数据库的类, ...

  2. C# Distinct去重泛型List

    List<int>去重 List<string>去重 List<T>去重 1. List<int>去重 List<int> ilist = ...

  3. centos7.6 安装Tomcat-8.5.39

    #关闭防火墙 systemctl stop firewalld.service systemctl disable firewalld setenforce sed -i '/SELINUX=/ s/ ...

  4. buildroot教程

    什么是buildroot Buildroot是Linux平台上一个开源的嵌入式Linux系统自动构建框架. 0.下载buildroot Buildroot版本每2个月,2月,5月,8月和11月发布一次 ...

  5. 九、ITK-VTK混合编程--将序列dcm图像通过ITK读去并通过VTK显示出来

    一.初步介绍 上一个博客里面我记录了VTK的安装,以及相关的工程代码的构建,但是实际上上一个博客测试的代码的例子仅仅只是VTK程序的例子.而我实际上希望能够实现的是VTK和ITK混合编程. 在这里还是 ...

  6. 集合系列 List(五):Stack

    Stack 是先进后出的栈结构,其并不直接实现具体的逻辑,而是通过继承 Vector 类,调用 Vector 类的方法实现. public class Stack<E> extends V ...

  7. [读论文]Shading-aware multi view stereo

    如何实现refine的? 几何误差和阴影误差如何加到一起? 为了解决什么问题? 弱纹理或无纹理:单纯的多视图立体算法在物体表面弱纹理或者无纹理区域重建完整度不够高,精度也不够高,因此结合阴影恢复形状来 ...

  8. python访问Apollo获取配置

    操作系统 : CentOS7.3.1611_x64 Python 版本 : 3.6.8 Apollo源码地址: https://github.com/ctripcorp/apollo 访问Apollo ...

  9. mysql 读写分离(手动和自动方法)

    使用sqlalchemy 使mysq自动读写分离: 代码如下: from flask import Flask from flask_sqlalchemy import SQLAlchemy, Sig ...

  10. python - 操作excel表格

    说明:由于公司oa暂缺,人事妹子在做考勤的时候,需要通过几个excel表格去交叉比对员工是否有旷工或迟到,工作量大而且容易出错. 这时候it屌丝的机会来啦,花了一天时间给妹子撸了一个自动化脚本. 1. ...