#import "CZJsonObject.h"
#import <objC/runtime.h>
#import <objc/message.h> NSString *setter_from_key(NSString *key)
{
//capitalise the first letter
NSString *setter = [key stringByReplacingCharactersInRange:NSMakeRange(, ) withString:[[key substringToIndex:] uppercaseString]];
//add 'set' and the colon
setter = [NSString stringWithFormat:@"set%@:", setter];
return setter;
} @implementation CZJsonObject - (void)fitNilInproperty
{
Class _targetClass = [self class];
while ([_targetClass class]!=[NSObject class]) {
[self fitNibWithClass:_targetClass];
_targetClass = [_targetClass superclass];
}
}
/*
* @waring 对于自定义getter和/或setter方法名的属性无效
*/
- (void)fitNibWithClass:(Class)class
{
//传出参数,获取属性的数量
unsigned int outCount = ;
//获取属性列表的副本(所指向的指针)
objc_property_t* ptable = class_copyPropertyList(class, &outCount);//执行后outCount等于类的属性数量
//备份列表指针,便于最后释放
objc_property_t* ptable_first = ptable;
//遍历属性列表
for (unsigned int index = ; index<outCount; index++) {
//获取 当前属性的@encode
const char* attrName = property_getAttributes(*ptable);
NSString* attrNameStr = [NSString stringWithCString:attrName encoding:NSUTF8StringEncoding];
//判断当前属性类型是否为对象
//若@encode以@T开头,则为id型(近似但不等于对象)
//若@encode以@T开头,而且匹配[".+"],则意味着属性为自定义对象类型(NS类包含在内)
if (([attrNameStr hasPrefix:@"T@"]) && ([attrNameStr rangeOfString:@"\".+\"" options:NSRegularExpressionSearch].location!=NSNotFound)) {
//获取当前属性 的 属性名
const char* propertyCName = property_getName(*ptable);
NSString* propertyName = [NSString stringWithCString:propertyCName encoding:NSUTF8StringEncoding];
//获取getter的方法名
NSString* getterName = propertyName;
//检查该getter是否存在,若getter被自定义,则getter名不等于属性名
BOOL isDefaultGetter = [self respondsToSelector:NSSelectorFromString(getterName)];
if (isDefaultGetter) {
//调用该属性的getter,获取属性值
NSObject* propertyValue = [self performSelector:NSSelectorFromString(getterName)];
//当属性值为nil

          if (propertyValue==nil||propertyValue==[NSNull null]||propertyValue==NULL) {

//从@encode分离类型信息

NSArray* attrArr = [attrNameStr componentsSeparatedByString:@"\""];

//取出属性类型名

NSString* propertyTypeClassName = [attrArr objectAtIndex:1];

//根据类型名获取默认值

NSObject* defaultValue = [self defaultValueWithClassType:propertyTypeClassName];

//同上,检查该getter是否为默认的setter

BOOL isDefaultSetter = [self respondsToSelector:NSSelectorFromString(setter_from_key(propertyName))];

if (isDefaultSetter) {

//调用setter,将默认值传人

[self performSelector:NSSelectorFromString(setter_from_key(propertyName)) withObject:defaultValue];

}

}

}

}

        //列表偏移到下一位属性
ptable++;
}
//遍历完成后,释放属性列表副本
free(ptable_first);
} - (id)defaultValueWithClassType:(NSString*)type
{
id result = [[NSObject alloc]init];
if ([type hasPrefix:@"NS"]) {
if ([type isEqualToString:@"NSString"]) {
result = @"";//[[NSString alloc]init];
}else if ([type isEqualToString:@"NSNumber"]) {
result = @;//[[NSNumber alloc]init];
}else if ([type isEqualToString:@"NSDictionary"]) {
result = [[NSDictionary alloc]init];
}else if ([type isEqualToString:@"NSArray"]) {
result = [[NSArray alloc]init];
}else if ([type isEqualToString:@"NSMutableDictionary"]) {
result = [[NSMutableDictionary alloc]initWithCapacity:];
}else if ([type isEqualToString:@"NSMutableArray"]) {
result = [[NSMutableArray alloc]initWithCapacity:];
}else if ([type isEqualToString:@"NSDate"]) {
result = [[NSDate alloc]initWithTimeIntervalSince1970:];
}else if ([type isEqualToString:@"NSData"]) {
result = [[NSData alloc]initWithBase64EncodedString:@" " options:NSDataBase64DecodingIgnoreUnknownCharacters];
}
}
return result;
} - (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
if ([key isEqualToString:@"id"]) {
_theId = value;
}else if([key isEqualToString:@"description"]){
_theDescription = value;
}else{
//NSLog(@"%@ underfine the property: @property(nonatomic,readwrite) %@ %@; = %@",[self class],[value class],key,value);
}
}

IOS开发 模型赋值 runtime的更多相关文章

  1. iOS开发之使用Runtime给Model类赋值

    本篇博客算是给网络缓存打个基础吧,本篇博客先给出简单也是最容易使用的把字典转成实体类的方法,然后在给出如何使用Runtime来给Model实体类赋值.本篇博客会介绍一部分,主要是字典的key与Mode ...

  2. iOS开发小技巧 - runtime适配字体

    iOS开发小技巧 - runtime适配字体 版权声明:本文为博主原创文章,未经博主允许不得转载,有问题可联系博主Email: liuyongjiesail@icloud.com 一个iOS开发项目无 ...

  3. iOS开发——高级篇——Runtime实际应用

    前言 本篇主要介绍Runtime在开发中的一些使用场景,顺便讲解了下MJExtension的底层实现 一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制, ...

  4. iOS开发——高级特性&Runtime运行时特性详解

    Runtime运行时特性详解 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的动态特性,使这门古老的语言焕发生机.主要内容如下: 引言 ...

  5. iOS开发笔记之Runtime实用总结

    前言 runtime的资料网上有很多了,部分有些晦涩难懂,我通过自己的学习方法总结一遍,主要讲一些常用的方法功能,以实用为主,我觉得用到印象才是最深刻的.另外runtime的知识还有很多,想要了解更多 ...

  6. IOS开发中关于runtime的认识

    首先要知道我们写的代码在程序运行过程中都会被转化成runtime的C代码执行. runtime突出的一点就是OC中消息传递机制的应用.objc_msgsend(target,SEL); 首先我们先看一 ...

  7. iOS开发——高级技术精选OC篇&Runtime之字典转模型实战

    Runtime之字典转模型实战 如果您还不知道什么是runtime,那么请先看看这几篇文章: http://www.cnblogs.com/iCocos/p/4734687.html http://w ...

  8. iOS开发之遍历Model类的属性并完善使用Runtime给Model类赋值

    在上篇博客<iOS开发之使用Runtime给Model类赋值>中介绍了如何使用运行时在实体类的基类中添加给实体类的属性赋值的方法,这个方法的前提是字典的Key必须和实体类的Property ...

  9. 我的iOS开发系列博文

    之前目录性的总结了发表过的关于OC方面的文章,今天在目录性的总结一下有关iOS开发的文章.走过路过不要错过哦,今天的博文也全都是干货.写技术博客与大家交流一下思想也是不错的. 下面是我的技术博客中有关 ...

随机推荐

  1. 实用SQL

    下列语句部分是MsSql语句,不可以在access中使用.SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE) DML—数据操纵语言(SELECT,DELETE,U ...

  2. JAVA虚拟机垃圾回收算法原理

    除了释放不再被引用的对象外,垃圾收集器还要处理堆碎块.新的对象分配了空间,不再被引用的对象被释放,所以堆内存的空闲位置介于活动的对象之间.请求分配新对象时可能不得不增大堆空间的大小,虽然可以使用的总空 ...

  3. 安装ss

    用的是centos , shell中执行如下命令 yum install python-setuptools && easy_install pip pip install shado ...

  4. java io流 运行错误时,保存异常到文件里面

    java io流 运行错误时,保存异常到文件里面 下面这个实例,运行后,输入数字,为正确,如果输入字符串,则报错,保存错误信息 //运行错误时,保存异常到文件里面 //下面这个实例,运行后,输入数字, ...

  5. debian8(jessie)安装小记

    其实上周五就想写这篇博客了,一直忙着没时间,虽然也不知道自己这一个星期到底在忙什么.这次我是彻底告别windows了,安装的过程略为艰辛,因为之前习惯了deepin和ubuntu的傻瓜式安装,而deb ...

  6. 【练习】flushback基于时间的闪回查询

    1.创建table t1 :: SCOTT@ORA11GR2>create table t1 as select * from scott.emp; Table created. :: SCOT ...

  7. 2016-08-05:samba服务器配置

    centos samba服务器配置 配置smb.conf文件 [share] path = /home/lee writable = yes 添加smb用户 smbpasswd -a root 启动s ...

  8. 9.S5PV210的时钟系统

    1.时钟域:MSYS.DSYS.PSYS(1)因为S5PV210的时钟体系比较复杂,内部外设模块太多,因此把整个内部的时钟划分为3大块,叫做3个域.(2)MSYS: CPU(Cortex-A8内核). ...

  9. cin判断读取结束 C++语言

    cin是C++的输入流,可以通过>>进行读取. 判断读取结束,一般有两种方法,具体取决于与输入的约定. 1 以特殊值结尾. 如输入整数,以-1结束,那么当读到-1的时候,就确定读取结束了. ...

  10. Python自动化 【第三篇】:Python基础-集合、文件操作、字符编码与转码、函数

    1.        集合 1.1      特性 集合是一个无序的,不重复的数据组合,主要作用如下: 去重,把一个列表变成集合实现自动去重. set可以看成数学意义上的无序和无重复元素的集合,因此,两 ...