#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实现归解档的更多相关文章

  1. Vue.js 源码分析(十六) 指令篇 v-on指令详解

    可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码,例如: <!DOCTYPE html> <html lang="en"& ...

  2. 第六十三篇:Vue的条件渲染与列表渲染

    好家伙, 1.条件渲染v-if 1.1.v-if基本使用 <body> <div id="app"> <p v-if="flag" ...

  3. “全栈2019”Java第六十三章:接口与抽象方法详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  4. Python开发【第十三篇】:jQuery(二)

    http://www.bubuko.com/infodetail-1438296.html 处理完毕需要整理贴进来 Python之路[第十三篇]jQuery案例-Form表单&插件及扩展   ...

  5. 十三篇系列:king转折点,wooga瓶颈,supercell营收结构

    转自:http://gamerboom.com/archives/95125 十三篇系列:king的历史转折点,wooga的瓶颈,supercell的营收结构 第一篇 这句话In other word ...

  6. Spring Cloud第十三篇 | Spring Boot Admin服务监控

    本文是Spring Cloud专栏的第十三篇文章,了解前十二篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Clo ...

  7. 解剖SQLSERVER 第十三篇 Integers在行压缩和页压缩里的存储格式揭秘(译)

    解剖SQLSERVER 第十三篇    Integers在行压缩和页压缩里的存储格式揭秘(译) http://improve.dk/the-anatomy-of-row-amp-page-compre ...

  8. 第十三篇 Integration Services:SSIS变量

    本篇文章是Integration Services系列的第十三篇,详细内容请参考原文. 简介在前一篇我们结合了之前所学的冒泡.日志记录.父子模式创建一个自定义的SSIS包日志记录模式.在这一篇,我们将 ...

  9. Python之路【第十三篇】:jQuery -暂无内容-待更新

    Python之路[第十三篇]:jQuery -暂无内容-待更新

随机推荐

  1. 多线程访问winform控件出现异常的解决方法

    一.  多线程访问winform控件出现异常的解决方法 1.  问题描述<1> 如果创建某控件的线程之外的其他线程试图调用该控件,则会引发一个 InvalidOperationExcept ...

  2. jsp页面用el表达式获取枚举的code

    jsp页面用el表达式获取枚举的code <c:set var="D_BUSINESS" value="<%=DeptEnum.D_BUSINESS%> ...

  3. BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树

    2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...

  4. android开发之Fragment加载到一个Activity中

    Fragments 是android3.0以后添加的.主要是为了方便android平板端的开发.方便适应不同大小的屏幕.此代码是为了最简单的Fragment的使用,往一个Activity中添加Frag ...

  5. 一个Windows Service项目的完整开发过程

    (一)建立项目文件 先建立一个解决方案文件,然后添加三个项目. 分别是: (1)Windows服务项目  -----ActiveMQSenderService项目,服务主要是定时轮询某表,将更新发送到 ...

  6. (ios开发学习笔记一)ios项目文件结构

    转自:http://www.cnblogs.com/macroxu-1982/archive/2012/07/31/2616389.html 下面是单个窗体项目例子,我们从这个项目开始,说明ios项目 ...

  7. Word2010 清除样式

    使用场景         有时候我们在网页上面粘贴一些精华文章或者从去整理别人已经完成的word的时候,会发现它自带的格式,可能并不是我们所理想的格式,所以此时就不得不去重新编辑其格式,但是word里 ...

  8. CISCO 双线接入MAP配置详解

      随着我国宽带技术的普及,各个公司都会有一至二条Internet接入线路,这些线路可能由电信.网通.长宽.联通等不同的IS提供,尽管他们在局端采用的技术可能有不同,但对客户而言都是同样接入方式,以太 ...

  9. C++_快速排序

    void quick_sort(int s[],int l,int r) { if(l<r) { int i=l,j=r,x=s[l]; while(i<j) { while( i< ...

  10. Android进阶笔记16:ListView篇之ListView刷新显示(全局 和 局部)

    一.ListView内容变化后,动态刷新的步骤(全局刷新): (1)更新适配器Adapter数据源:(不要使用匿名内部类) (2)调用适配器Adapter的刷新方法notifyDataSetChang ...