美文网首页iOS开发
IOSRunTime_OC的序列化

IOSRunTime_OC的序列化

作者: _CLAY_ | 来源:发表于2017-04-03 18:44 被阅读68次

    利用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
    

    相关文章

      网友评论

        本文标题:IOSRunTime_OC的序列化

        本文链接:https://www.haomeiwen.com/subject/ozsoottx.html