#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. linux重启oracle 各种方法

    在linux下重启oracle数据库及监听器总结: 方法1: 用root以ssh登录到linux,打开终端输入以下命令: cd $ORACLE_HOME   #进入到oracle的安装目录 dbsta ...

  2. 禁止Android的StatusBar下拉

    Android中有许多隐藏的Service,StatusBarManager就是其中一个,在Context.java中可以看到: /** * Use with {@link #getSystemSer ...

  3. mybatis 关联映射传递多参数方法

    <resultMap type="com.secoo.my.bean.OrderItemComment" id="orderItemResult"> ...

  4. ORACLE触发器具体解释

    ORACLE PL/SQL编程之八: 把触发器说透 本篇主要内容例如以下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 ...

  5. 判断手机andriod还是iphone

    手机识别:var isAndroid = navigator.appVersion.toLowerCase().indexOf(‘android’) >= 0,isIphone = naviga ...

  6. vim中光标的前进和后退

    流行的文本编辑器通常都有前进和后退功能,可以在文件中曾经浏览过的位置之间来回移动.在 vim 中使用 Ctrl-O 执行后退,使用 Ctrl-I 执行前进.相关帮助: :help CTRL-O  :h ...

  7. this的分析

    this是js中的一个关键字,当函数运行时,会自动生成的一个对象,只能在函数内部使用.随着函使用场合不同,this值会变化,但是始终指向调用函数的那个对象. 1.纯粹的函数调用 function bo ...

  8. javascript oop深入学习笔记(一)

    一.定义和实例化一个类: 在OOP的思想中,类是一个很重要的元素,一个类表示了具有相似的一类事物的抽象,通过实例化一个类,可以获得属于该类的一个实例,我们也可以称之为对象. 在javascript中, ...

  9. iOS 成员变量,实例变量,属性变量的区别,联系

    在ios第一版中: 我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如: 注意:(这个是以前的用法) @interface MyV ...

  10. CentOS/Linux安装VNCserver

    VNC全称是Virtual Network Computing,属于远程控制类软件.其优点是支持跨操作系统的远程图形化控制.在日常工作中,服务器常常是存在机房,不可能每次需要图形界面操作就跑到机房,因 ...