iOS 自定义对象及子类及模型套模型的拷贝归档存储的通用代码

Posted 张林峰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS 自定义对象及子类及模型套模型的拷贝归档存储的通用代码相关的知识,希望对你有一定的参考价值。

一、runtime实现通用copy

如果自定义类的子类,模型套模型你真的会copy吗,小心有坑。

copy需要自定义类继承NSCopying协议

#import <objc/runtime.h>

- (id)copyWithZone:(NSZone *)zone {
    
    id obj = [[[self class] allocWithZone:zone] init];
    Class class = [self class];
    while (class != [NSObject class]) {
        unsigned int count;
        Ivar *ivar = class_copyIvarList(class, &count);
        for (int i = 0; i < count; i++) {
            Ivar iv = ivar[i];
            const char *name = ivar_getName(iv);
            NSString *strName = [NSString stringWithUTF8String:name];
            //利用KVC取值
            id value = [[self valueForKey:strName] copy];//如果还套了模型也要copy呢
            [obj setValue:value forKey:strName];
        }
        free(ivar);
        
        class = class_getSuperclass(class);//记住还要遍历父类的属性呢
    }
    return obj;
}

二、runtime实现通用归档解档

归档解档需要自定义类继承NSCoding协议

#import <objc/runtime.h>

#pragma
mark - 归档、解档 - (void)encodeWithCoder:(NSCoder *)encoder { Class class = [self class]; while (class != [NSObject class]) { unsigned int count; Ivar *ivar = class_copyIvarList(class, &count); for (int i = 0; i < count; i++) { Ivar iv = ivar[i]; const char *name = ivar_getName(iv); NSString *strName = [NSString stringWithUTF8String:name]; //利用KVC取值 id value = [self valueForKey:strName]; [encoder encodeObject:value forKey:strName]; } free(ivar); class = class_getSuperclass(class);//记住还要遍历父类的属性呢 } } - (id)initWithCoder:(NSCoder *)decoder { self = [super init]; if (self) { Class class = [self class]; while (class != [NSObject class]) { unsigned int count = 0; //获取类中所有成员变量名 Ivar *ivar = class_copyIvarList(class, &count); for (int i = 0; i < count; i++) { Ivar iva = ivar[i]; const char *name = ivar_getName(iva); NSString *strName = [NSString stringWithUTF8String:name]; //进行解档取值 id value = [decoder decodeObjectForKey:strName]; //利用KVC对属性赋值 [self setValue:value forKey:strName]; } free(ivar); class = class_getSuperclass(class);//记住还要遍历父类的属性呢 } } return self; }

三、NSUserDefaults存储自定义对象

//1.自定义类继承NSCoding协议,并实现归档解档,前面介绍过了,不多说

//2.将自定义对象转NSData
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:student];

//3.存到NSUserDefaults
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"myStudent"];
[[NSUserDefaults standardUserDefaults] synchronize];//这句要写,很多人都忘了

//4.存数组,数组中包含自定义对象
[dataArray addObject:data];//这个data是第2步归档得到的data

//5.NSUserDefaults只能存不可变数组,不要忘了转换成不可变
NSArray * array = [NSArray arrayWithArray:dataArray];
[[NSUserDefaults standardUserDefaults] setObject:array forKey:@"students"];

四、NSUserDefaults中读取归档的自定义对象

NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"myStudent"];
Student *student = [NSKeyedUnarchiver unarchiveObjectWithData:data];

 



以上是关于iOS 自定义对象及子类及模型套模型的拷贝归档存储的通用代码的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中归档自定义对象 - 扩展

带有循环的 NSManagedObject 子类的深拷贝

IOS 数据存储(NSKeyedArchiver 归档篇)

iOS 对模型对象进行归档

Unix下IO模型及他们之间的区别

iOS 浅谈MVC设计模式及Controllers之间的传值方式