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开发的文章.走过路过不要错过哦,今天的博文也全都是干货.写技术博客与大家交流一下思想也是不错的. 下面是我的技术博客中有关 ...
随机推荐
- PhpStorm中字体大小的改变方法
文件->设置->编辑器->编辑器->鼠标->用Ctrl+鼠标滚轮改变字体大小(缩放)(在前边的复选框里打钩,确定,就可以了)
- ISurfaceOp 接口生成等高线
(1)ISurfaceOp.Contour 根据DEM生成等高线图层: private void button1_Click(object sender, EventArgs e) { ...
- mac下配置openfire
下载 在浏览器中打开如下网址http://www.igniterealtime.org/downloads/index.jsp,根据你的操作系统选择对应的版本进行下载,这里我是在mac下配置的,所以选 ...
- .Net的Excel 导出 格式设置
添加引用:Microsoft Excel 11.0 Object Library ; 添加:using Microsoft.Office.Interop.Excel; 一.打开Exce ...
- [转载]: delphi中XLSReadWrite控件的使用(2)---delphi XE下安装
一.下载 官方下载网址: http://www.axolot.com/components/download.htm 从这里可以下载到从Delphi5到DelphiXE全部支持的版本. 二.软件安装 ...
- 去除VA(Visual Assist)中文注释的红色波浪线
VS版本:vs2015 番茄版本:VA_X.dll file version 10.9.2089.0 built 2016.02.01 1.打开番茄设置 2.去掉 Underlining->Un ...
- 【转】JVM 堆内存设置原理
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- JStorm第一个程序WordCount详解
一.Strom基本知识(回顾) 1,首先明确Storm各个组件的作用,包括Nimbus,Supervisor,Spout,Bolt,Task,Worker,Tuple nimbus是整个storm任务 ...
- mac 安装Homebrew
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
- 查看真机的APP沙盒文件
1.Xcode --> window --> devices -->左边选择设备 右下边选择要查看的app 双击应用可查看目录 点击设置按钮,选 Download Container ...