Runtime应用(三)实现NSCoding的自动归档和自动解档

当我们需要将一个对象进行归档时,都要让该对象的类遵守NSCoding协议,再实现归档和接档方法。例如有一个Person类,该类有两个成员变量

@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) int age;

两个协议的实现方法如下

/**
 *  将对象写入某个文件时需要调用,在该方法中说明哪些属性需要存储
 */
- (void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:self.name forKey:@"name"];
    [encoder encodeInt:self.age forKey:@"age"];
}

/**
 *  从文件中解析对象时会调用,在该方法中解析对象的属性
 */
- (id)initWithCoder:(NSCoder *)decoder
{
    if (self = [super init]) {
        // 解析之后要赋值给属性
        _name = [decoder decodeObjectForKey:@"name"];
        _age = [decoder decodeIntForKey:@"age"];
    }
    return self;
}

但当该类拥有上百个属性时,那将会花费更多的功夫在重复代码上,所以使用运行时机制截取类的成员变量,进行赋值

例如有一个狗类Dog和它的父类动物类Animal

狗类的成员变量有

@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) int age;

动物类的成员变量有

@property (nonatomic,assign) double weight;

当我们需要将狗对象进行归档时,可以在类中这样重写归档和解档方法

- (id)initWithCoder:(NSCoder *)aDecoder
{

    if (self = [super init]) {
        Class c = self.class;
        // 截取类和父类的成员变量
        while (c && c != [NSObject class]) {
            unsigned int count = 0;
            Ivar *ivars = class_copyIvarList(c, &count);
            for (int i = 0; i < count; i++) {

                NSString *key = [NSString stringWithUTF8String:ivar_getName(ivars[i])];

                id value = [aDecoder decodeObjectForKey:key];

                [self setValue:value forKey:key];

            }
            // 获得c的父类
            c = [c superclass];
            free(ivar);
        }

    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{

     Class c = self.class;
    // 截取类和父类的成员变量
    while (c && c != [NSObject class]) {
        unsigned int count = 0;

        Ivar *ivars = class_copyIvarList(c, &count);

        for (int i = 0; i < count; i++) {
            Ivar ivar = ivars[i];
            NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];

            id value = [self valueForKey:key];

            [aCoder encodeObject:value forKey:key];
        }
        c = [c superclass];
        // 释放内存
        free(ivar);
    }

}

代码测试:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    CXDog *d = [[CXDogalloc] init];
    d.name = @"cx";
    d.age = 12;
    d.weight = 1.55;
    // 将对象归档
    [NSKeyedArchiverarchiveRootObject:d toFile:@"/Users/c_xie/Desktop/wj.xxoo"];
    // 将对象解档
    CXDog *dog = [NSKeyedUnarchiverunarchiveObjectWithFile:@"/Users/c_xie/Desktop/wj.xxoo"];
    NSLog(@"%@,%d,%f",dog.name,dog.age,d.weight);

}

以后就算有再多的属性,一个循环搞定

时间: 2024-11-07 20:38:24

Runtime应用(三)实现NSCoding的自动归档和自动解档的相关文章

归档 Archive、解档Unchive、 XML(一)

1 使用归档的方式保存文件 1.1 问题 归档是任何对象都可以实现的更常规的方式,可以进行归档的对象需要实现NSCoding协议,而且每个实例变量应该是基本数据类型或者是实现NSCoding协议的某个类的实例.本案例使用归档NSKeyedArchiver和反归档NSKeyedUnarchiver将TRPerson对象写入和读取文件. 1.2 方案 首先创建一个TRPerson类,继承至NSObject,该类有两个属性NSString类型的name和NSInteger类型的age. 其次TRPer

iOS归档解档

使用NSKeyedArichiver进行归档.NSKeyedUnarchiver进行接档,这种方式会在写入.读出数据之前对数据进行序列化.反序列化操作. 1.对单个字符串归档 //获取根目录 NSString *homeDictionary = NSHomeDirectory(); //添加储存的文件名 NSString *homePath = [homeDictionary stringByAppendingPathComponent:@"myText.txt"]; //归档一个字符

归档 解档

//系统类型的对象归档(NSString/NSArray/NSDictionary) //1.设置归档路径,该路径需要详细到文件(不能是文件夹) //2.得到要归档的对象 //3.通过NSKeyedArchiver调用archiveRootObject方法,进行归档 //4.解档 通过NSKeyedUnarchiver调用unarchiveObjectWithFile进行解档,注意,该方法返回值类型为id //字符串的归档 解档 NSString *path = NSHomeDirectory(

(转发)IOS高级开发~Runtime(三)

11.系统类的方法实现部分替换 - (void) methodExchange { Method m1 = class_getInstanceMethod([NSStringclass],@selector(lowercaseString)); Method m2 = class_getInstanceMethod([NSStringclass],@selector(uppercaseString)); method_exchangeImplementations(m1, m2); NSLog(

IOS利用objc/runtime和KVC——快速归档解档

开发过程中有时需要存储一些轻量级的数据,对于IOS提供的几种数据存储方式在这时最合适当属对象归档:NSCoding 但是将对象数据进行归档解档时候需要实现两个方法: encodeWithCoder和initWithEncoder.encodeWithCoder就是编码,initWithCoder就是解码. encodeWithCoder方法传入的是一个NSCoder对象,实现的时候我们就可以调用encodeObject.encodeFloat. encodeInt等各种方法并通过指定键值进行编码

《Objective-C Runtime分析(三)-objc_msgSend》

本系列主要参考资料: Objective-C Runtime ReferenceObjective-C Runtime Programming Guide涉及主要文件:objc/message.h,objc/objc-api.h,objc/objc.h,objc/runtime.h特酷吧[tekuba.net]采用"署名-非商业用途-保持一致"的创作共用协议,使用本文内容请遵循该协议 Objective-C Runtime是Objective-C的基础内容,理解了Objective-C

Swift 使用Runtime对模型进行归档解档

Swift 使用Runtime对模型进行归档解档 func encode(with aCoder: NSCoder) { var count: UInt32 = 0 let propertyList = class_copyPropertyList(self.classForCoder, &count) for index in 0..<Int(count) { guard let pty = propertyList?[index], let cName = property_getNam

如何手工启动数据库自动归档模式

如果在Oracle安装时没有开启自动归档的模式的话,需要手工启动归档模式. a)        修改log_archive_start定义是否自动归档,10g版本后,这个参数作废,即使值是FALSE也自动归档,当前系统是11g,所以无需更改. b)        可以修改log_archive_format定义归档文件格式,一般使用默认值即可. c)        修改log_archive_dest_1,设置归档文件的目标目录. alter system set log_archive_des

自动归档autoArchive By H.l

写点简单的代码,让开发更简单 详情:ios 应用实现快速的临时缓存之模型的自动归档 Demo:http://files.cnblogs.com/files/sixindev/AutoArchiver.zip 优点:1.模型里无需写一行代码即可自动归档(调用方法2)  2.支持将NSDictionary 转化成模型,支持字典数组转换成模型数组 用法:只需要在模型里面引入 NSObject+JKCoding.h 头文件即可 方法1.字典转模型 NSDictionary *dic [email pro