IOS开发 模型赋值 runtime
#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的更多相关文章
- iOS开发之使用Runtime给Model类赋值
本篇博客算是给网络缓存打个基础吧,本篇博客先给出简单也是最容易使用的把字典转成实体类的方法,然后在给出如何使用Runtime来给Model实体类赋值.本篇博客会介绍一部分,主要是字典的key与Mode ...
- iOS开发小技巧 - runtime适配字体
iOS开发小技巧 - runtime适配字体 版权声明:本文为博主原创文章,未经博主允许不得转载,有问题可联系博主Email: liuyongjiesail@icloud.com 一个iOS开发项目无 ...
- iOS开发——高级篇——Runtime实际应用
前言 本篇主要介绍Runtime在开发中的一些使用场景,顺便讲解了下MJExtension的底层实现 一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制, ...
- iOS开发——高级特性&Runtime运行时特性详解
Runtime运行时特性详解 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的动态特性,使这门古老的语言焕发生机.主要内容如下: 引言 ...
- iOS开发笔记之Runtime实用总结
前言 runtime的资料网上有很多了,部分有些晦涩难懂,我通过自己的学习方法总结一遍,主要讲一些常用的方法功能,以实用为主,我觉得用到印象才是最深刻的.另外runtime的知识还有很多,想要了解更多 ...
- IOS开发中关于runtime的认识
首先要知道我们写的代码在程序运行过程中都会被转化成runtime的C代码执行. runtime突出的一点就是OC中消息传递机制的应用.objc_msgsend(target,SEL); 首先我们先看一 ...
- iOS开发——高级技术精选OC篇&Runtime之字典转模型实战
Runtime之字典转模型实战 如果您还不知道什么是runtime,那么请先看看这几篇文章: http://www.cnblogs.com/iCocos/p/4734687.html http://w ...
- iOS开发之遍历Model类的属性并完善使用Runtime给Model类赋值
在上篇博客<iOS开发之使用Runtime给Model类赋值>中介绍了如何使用运行时在实体类的基类中添加给实体类的属性赋值的方法,这个方法的前提是字典的Key必须和实体类的Property ...
- 我的iOS开发系列博文
之前目录性的总结了发表过的关于OC方面的文章,今天在目录性的总结一下有关iOS开发的文章.走过路过不要错过哦,今天的博文也全都是干货.写技术博客与大家交流一下思想也是不错的. 下面是我的技术博客中有关 ...
随机推荐
- TCP/UDP的接收包方式
UDP udp不是流式的,每次接收一个包,长度不超过(65535-28,总包长65535字节,包头28字节).所以UDP方式下不需要填写任何参数直接调用 $client->recv() 即可.注 ...
- AsynTask用法
http://blog.csdn.net/liuhe688/article/details/6532519 在Android中实现异步任务机制有两种方式,Handler和AsyncTask. Hand ...
- asp.net 运行时,"未能映射路径"
asp.net 站点出现:未能映射路径,解决方案之一:发现原来是iis 应用程序池中设置了.net framework 版本为4.0了,而且VS中站点的版本为2.0引起的. 解决方案是把VS 中的站点 ...
- textContent 与innerText
转自下面这位大神: http://zhangyaochun.iteye.com/blog/1391370 其实关于这textContent与innerText有很多碎碎的东西,不过个人觉得还是一个不错 ...
- android常见面试问题
重:Listview中多个类型的条目如何处理?如果条目里边有button,会出现什么问题?如何处理?如果条目里边有checkbox会出现什么问题,如何解决?(这三个问题有过开发经验都应该遇到过). 在 ...
- {Links}{Matting}{Saliency Detection}{Superpixel}Source links
自然图像抠图/视频抠像技术发展情况梳理(image matting, alpha matting, video matting)--计算机视觉专题1 http://blog.csdn.net/ansh ...
- 基于HOG-3D的时空描述子
作者提出一种新的基于局部描述子的行为识别算法.
- 《Linux内核设计与实现》读书笔记 第一章 Linux内核简介
一.相关历史 1. Unix内核的特点 简洁:仅提供系统调用并有一个非常明确的设计目的 抽象:几乎所有东西都被当做文件 可移植性:使用C语言编写,使得其在各种硬件体系架构面前都具备令人惊异的移植能力 ...
- 信息安全系统设计基础课程实践:简单TUI游戏设计
简单TUI游戏设计 目 录 一 Curses库简介与基本开发方法 ...
- ubuntu 14 配置 tomcat
参考 http://www.linuxidc.com/Linux/2015-01/111119.htm