利用RunTime运行时,遍历一个类的所有属性和方法。
序列化-----归档
反序列化--解档
在iOS中一个自定义对象是无法直接存入到文件中的,必须先转化成二进制流才行。从对象到二进制数据的过程我们一般称为对象的序列化(Serialization),也称为归档(Archive)。同理,从二进制数据到对象的过程一般称为反序列化或者反归档
Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject<NSCoding>
/**
年龄
*/
@property (nonatomic, assign) int age;
/**
名称
*/
@property (nonatomic, copy) NSString *name;
@end
Person.m
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeInt:_age forKey:@"age"];
//实际开发中会遇到多种属性如果一一列出十分麻烦(解决思路如下)
// for (int i = 0; i < 属性的个数; i ++) {
// //取出一个属性的值和名称
// value
// key
// [aCoder encodeObject:value forKey:key];
// }
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super init];
if (self) {
//解档
_name = [coder decodeObjectForKey:@"name"];
_age = [coder decodeIntForKey:@"age"];
}
return self;
}
@end
ViewController.m
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%@",NSTemporaryDirectory());
}
- (IBAction)save:(UIButton *)sender {
Person *p = [Person new];
p.name = @"LL";
p.age = 18;
//归档路径
NSString *temp = NSTemporaryDirectory();
NSString *filePath = [temp stringByAppendingPathComponent:@"LL.LOVE"];
//归档
[NSKeyedArchiver archiveRootObject:p toFile:filePath];
}
- (IBAction)read:(UIButton *)sender {
//归档路径
NSString *temp = NSTemporaryDirectory();
NSString *filePath = [temp stringByAppendingPathComponent:@"LL.LOVE"];
//解档
Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
NSLog(@"%@--%d",p.name,p.age);
}
@end
以下部分为利用RunTime运行时,遍历一个类的所有属性和方法,优化了序列化、反序列化多种属性的问题
Person.m
#import "Person.h"
#import <objc/message.h>
@interface Person ()
@property (nonatomic,copy) NSString *name_X;//runtime中不存在私有 此属性依然可以获取
@end
- (void)encodeWithCoder:(NSCoder *)aCoder {
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([Person class], &count);
for (int i = 0; i < count; i ++) {
//拿出属性的名称
Ivar ivar = ivars[i];
const char * name = ivar_getName(ivar);
NSString *key = [NSString stringWithUTF8String:name];
//取出属性的值
id value = [self valueForKey:key];
//归档
[aCoder encodeObject:value forKey:key];
}
//C语音需要释放指针
free(ivars);
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super init];
if (self) {
//解档
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([Person class], &count);
for (int i = 0; i < count; i ++) {
//拿出属性的名称
Ivar ivar = ivars[i];
const char * name = ivar_getName(ivar);
NSString *key = [NSString stringWithUTF8String:name];
//解档
id value = [coder decodeObjectForKey:key];
//将值设置到属性上 KVC
[self setValue:value forKey:key];
}
//C语音需要释放指针
free(ivars);
}
return self;
}
@end