第六十三篇、runtime实现归解档
#import <objc/runtime.h>
#import <objc/message.h> @implementation HDFArchiveModel - (void)encodeWithCoder:(NSCoder *)aCoder {
unsigned int outCount = ;
Ivar *ivars = class_copyIvarList([self class], &outCount); for (unsigned int i = ; i < outCount; ++i) {
Ivar ivar = ivars[i]; // 获取成员变量名
const void *name = ivar_getName(ivar);
NSString *ivarName = [NSString stringWithUTF8String:name];
// 去掉成员变量的下划线
ivarName = [ivarName substringFromIndex:]; // 获取getter方法
SEL getter = NSSelectorFromString(ivarName);
if ([self respondsToSelector:getter]) {
const void *typeEncoding = ivar_getTypeEncoding(ivar);
NSString *type = [NSString stringWithUTF8String:typeEncoding]; // const void *
if ([type isEqualToString:@"r^v"]) {
const char *value = ((const void *(*)(id, SEL))(void *)objc_msgSend)((id)self, getter);
NSString *utf8Value = [NSString stringWithUTF8String:value];
[aCoder encodeObject:utf8Value forKey:ivarName];
continue;
}
// int
else if ([type isEqualToString:@"i"]) {
int value = ((int (*)(id, SEL))(void *)objc_msgSend)((id)self, getter);
[aCoder encodeObject:@(value) forKey:ivarName];
continue;
}
// float
else if ([type isEqualToString:@"f"]) {
float value = ((float (*)(id, SEL))(void *)objc_msgSend)((id)self, getter);
[aCoder encodeObject:@(value) forKey:ivarName];
continue;
} id value = ((id (*)(id, SEL))(void *)objc_msgSend)((id)self, getter);
if (value != nil && [value respondsToSelector:@selector(encodeWithCoder:)]) {
[aCoder encodeObject:value forKey:ivarName];
}
}
} free(ivars);
} - (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
unsigned int outCount = ;
Ivar *ivars = class_copyIvarList([self class], &outCount); for (unsigned int i = ; i < outCount; ++i) {
Ivar ivar = ivars[i]; // 获取成员变量名
const void *name = ivar_getName(ivar);
NSString *ivarName = [NSString stringWithUTF8String:name];
// 去掉成员变量的下划线
ivarName = [ivarName substringFromIndex:];
// 生成setter格式
NSString *setterName = ivarName;
// 那么一定是字母开头
if (![setterName hasPrefix:@"_"]) {
NSString *firstLetter = [NSString stringWithFormat:@"%c", [setterName characterAtIndex:]];
setterName = [setterName substringFromIndex:];
setterName = [NSString stringWithFormat:@"%@%@", firstLetter.uppercaseString, setterName];
}
setterName = [NSString stringWithFormat:@"set%@:", setterName];
// 获取getter方法
SEL setter = NSSelectorFromString(setterName);
if ([self respondsToSelector:setter]) {
// 获取数据的类型
const void *typeEncoding = ivar_getTypeEncoding(ivar);
NSString *type = [NSString stringWithUTF8String:typeEncoding];
NSLog(@"%@", type); // const void *
if ([type isEqualToString:@"r^v"]) {
NSString *value = [aDecoder decodeObjectForKey:ivarName];
if (value) {
((void (*)(id, SEL, const void *))objc_msgSend)(self, setter, value.UTF8String);
} continue;
}
// int
else if ([type isEqualToString:@"i"]) {
NSNumber *value = [aDecoder decodeObjectForKey:ivarName];
if (value != nil) {
((void (*)(id, SEL, int))objc_msgSend)(self, setter, [value intValue]);
}
continue;
} else if ([type isEqualToString:@"f"]) {
NSNumber *value = [aDecoder decodeObjectForKey:ivarName];
if (value != nil) {
((void (*)(id, SEL, float))objc_msgSend)(self, setter, [value floatValue]);
}
continue;
} // object
id value = [aDecoder decodeObjectForKey:ivarName];
if (value != nil) {
((void (*)(id, SEL, id))objc_msgSend)(self, setter, value);
}
}
} free(ivars);
} return self;
} + (void)test {
HDFArchiveModel *archiveModel = [[HDFArchiveModel alloc] init];
archiveModel.archive = @"自动归档";
archiveModel.session = "http://www.henishuo.com";
archiveModel.totalCount = @();
archiveModel.referenceCount = ;
archiveModel._floatValue = 10.0; NSString *path = NSHomeDirectory();
path = [NSString stringWithFormat:@"%@/archive", path];
[NSKeyedArchiver archiveRootObject:archiveModel
toFile:path]; HDFArchiveModel *unarchiveModel = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; } @end
第六十三篇、runtime实现归解档的更多相关文章
- Vue.js 源码分析(十六) 指令篇 v-on指令详解
可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码,例如: <!DOCTYPE html> <html lang="en"& ...
- 第六十三篇:Vue的条件渲染与列表渲染
好家伙, 1.条件渲染v-if 1.1.v-if基本使用 <body> <div id="app"> <p v-if="flag" ...
- “全栈2019”Java第六十三章:接口与抽象方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- Python开发【第十三篇】:jQuery(二)
http://www.bubuko.com/infodetail-1438296.html 处理完毕需要整理贴进来 Python之路[第十三篇]jQuery案例-Form表单&插件及扩展 ...
- 十三篇系列:king转折点,wooga瓶颈,supercell营收结构
转自:http://gamerboom.com/archives/95125 十三篇系列:king的历史转折点,wooga的瓶颈,supercell的营收结构 第一篇 这句话In other word ...
- Spring Cloud第十三篇 | Spring Boot Admin服务监控
本文是Spring Cloud专栏的第十三篇文章,了解前十二篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Clo ...
- 解剖SQLSERVER 第十三篇 Integers在行压缩和页压缩里的存储格式揭秘(译)
解剖SQLSERVER 第十三篇 Integers在行压缩和页压缩里的存储格式揭秘(译) http://improve.dk/the-anatomy-of-row-amp-page-compre ...
- 第十三篇 Integration Services:SSIS变量
本篇文章是Integration Services系列的第十三篇,详细内容请参考原文. 简介在前一篇我们结合了之前所学的冒泡.日志记录.父子模式创建一个自定义的SSIS包日志记录模式.在这一篇,我们将 ...
- Python之路【第十三篇】:jQuery -暂无内容-待更新
Python之路[第十三篇]:jQuery -暂无内容-待更新
随机推荐
- 瑞丽的SQL-基于窗体的排名计算
在SQL Server中,窗体被定义为用户指定的一组行. 之所以要提出窗体这个概念,由于这种基于窗体或分区的又一次计算在实际工作应用范围比較广泛.比如.假设我们要对每一个班级中的学生按成绩进行排序,在 ...
- 一个不错的JavaScript解析浏览器路径方法(转)
JavaScript中有时需要用到当前的请求路径等涉及到url的情况,正常情况下我们可以使用location对象来获取我们需要的信息,本文从另外一个途径来解决这个问题,而且更加巧妙 方法如下: fun ...
- hdu4864 hdu4268 贪心 lower_bound
hdu4864 题意: 有n个机器,m个任务,n,m<=100000,每个机器都有工作时间的最大限制xi(0<xi<1440)和完成的最大难度yi(0<=yi<=100) ...
- TOJ 4325 RMQ with Shifts / 线段树单点更新
RMQ with Shifts 时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte 描述 In the traditional RMQ (Range M ...
- ABAP EXCEL 文件上传下载 用SMW0
T-CODE: SMW0 在这里只介绍二进制数据,HTML模板的上传也一样. 另外也可以用CBO TABLE管理文件 可以看我另一个博文:CBO TABLE管理文件上传下载 选择 二进制 写包名: 进 ...
- StarlingMVC Framework中文教程
配置与开始 将Starling项目配置为StarlingMVC项目,仅需几行代码.在继承于starling.display.Sprite的起始类里,创建一个StarlingMVC的实例,并传递给它三个 ...
- 设置用户ID和设置组ID
与一个进程关联的ID有6个或更多,如下图所示: 与每个进程相关联的用户ID和组ID 实际用户ID 实际组ID 我们实际是谁 有效用户ID 有效组ID 附加组ID 用于文件访问权限检索 保存的设置用户I ...
- UITableView优化技巧
UITableView的简单认识 UITableView最核心的思想就是UITableViewCell的重用机制.简单的理解就是:UITableView只会创建一屏幕(或一屏幕多一点)的UITable ...
- Asp.Net 之 WebService部署到服务器后出现" The test form is only available for requests from the local machine "
最近由于任务需要开发了一个WebService, 部署到服务器以后,出现上述问题,网上查找到如下解决方案: 问题原因: 从 NET Framework 1.1 起定义了一个名为 HttpPostLoc ...
- C# 之 无法嵌入互操作类型(Word 或 Excel 操作)
Microsoft.Office.Interop.Excel.Application eApp = new Microsoft.Office.Interop.Excel.ApplicationClas ...