运行时使用系列(一)
简介:
runtime是底层的一套API,平时写的OC代码经过编译器最终都会转为runtime代码;
一、归档和反归档:
1、可以把一个对象保存到文件中或者把一个对象从文件中读取出来;
2、一个对象的属性只有几个的话,进行常规的归档操作就可以搞定了,但是如果属性多达几十个,这个时候再使用常规的归档方法就显得没有意义,浪费时间,降低效率了,这时候可以利用runtime的一些方法来帮助我们快速的进行归档和反归档。
代码如下:
1、这里需要归档的对象为ArchivedObject
2、.h文件内容如下:
#import <Foundation/Foundation.h>
@interface ArchivedObject : NSObject<NSCoding>
@property (nonatomic, assign) int age;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) double height;
@end
注意:这里归档的对象所属于的类需要遵循NSCoding协议才可以
3、.m文件内容如下:
#import "ArchivedObject.h"
#import <objc/runtime.h>
@implementation ArchivedObject
- (void)encodeWithCoder:(NSCoder *)aCoder{
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([ArchivedObject class], &count); //获取所有的成员变量
for (int i = 0; i < count; i++) { //遍历所有的成员变量
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar); //获取成员变量名称
NSString *key = [NSString stringWithUTF8String:name]; //以成员变量作为key值
id value = [self valueForKey:key]; //键值对获取value值
[aCoder encodeObject:value forKey:key]; //归档
}
free(ivars);
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([ArchivedObject class], &count); //获取所有的成员变量
for (int i = 0; i < count; i++) { //遍历所有的成员变量
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar); //获取成员变量名称
NSString *key = [NSString stringWithUTF8String:name]; //以成员变量作为key值
id value = [aDecoder decodeObjectForKey:key]; //反归档
[self setValue:value forKey:key]; //键值对设置value值
}
free(ivars);
}
return self;
}
@end
注意:
(1)这里需要在encodeWithCoder和initWithCoder两个方法中进行一些处理;
(2)使用的runtime的一些方法:
class_copyIvarList — 获取所有的成员变量;
ivar_getName — 获取一个成员变量的名称,转化为oc的字符串,作为key值;
4、在需要使用的地方调用,这里为ViewController.m文件中
4.1、归档:
- (IBAction)archiver:(UIButton *)sender {
ArchivedObject *object = [[ArchivedObject alloc] init];
object.age = 40;
object.name = @"jack";
object.height = 100.0;
NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *fileName = [filePath stringByAppendingPathComponent:@"archive.plist"];
[NSKeyedArchiver archiveRootObject:object toFile:fileName];
}
注意:这里归档时保存到沙盒中,文件格式为plist,结果为:
4.2、反归档:
- (IBAction)unarchiver:(id)sender {
NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *fileName = [filePath stringByAppendingPathComponent:@"archive.plist"];
ArchivedObject *object = [NSKeyedUnarchiver unarchiveObjectWithFile:fileName];
NSLog(@"%d---%@----%f", object.age, object.name, object.height);
//40---jack----100.000000
}
代码地址:
https://github.com/oceanfive/Runtime
最后:
这是runtime的一些简单使用,后续会继续挖掘更多内容。