iOS开发

IOSRunTime_OC的序列化

2017-04-03  本文已影响68人  _CLAY_

利用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
上一篇下一篇

猜你喜欢

热点阅读