iOS开发过程中一些数据的存储归档

来源:互联网 发布:手机打鱼软件开发 编辑:程序博客网 时间:2024/04/29 06:15

iOS开发难免会有数据的存储,对于一些常规的对象即简单地对象,文件读写只支持NSString,NSarray ,NDictionary,NSdata,既简单对象的数据持久化那么对于一些自定义的复杂类对象我们就需要进行数据的归档存储,一般我们对于一些比较复杂的数据对象的归档大致分为下列几个步骤:
1. 复杂对象写入文件,必须先转化成为NSData
2. 复杂对象只能通过归档(序列化,编码)转化为NSData
3. 对复杂对象实现归档的要求:

  • 复杂对象需要遵守协议
  • 复杂对象的属性,实例变量,如果是对象类型,也必须遵守协议

eg:列举一个归档的例子,如果针对一个Person对象进行归档代码如下:

Person.h文件如下

@interface Person : NSObject<NSCoding>@property(nonatomic,retain)NSString * name;@property(nonatomic,assign)NSInteger age;@property(nonatomic,retain)NSString * gender;@end

Person.m文件如下

@implementation Person//对Person对象进行编码时候,此方法执行。//对person中要想进行归档的所有属性,进行编码操作- (void)encodeWithCoder:(NSCoder *)aCoder{    [aCoder encodeObject:self.name forKey:@"name"];    [aCoder encodeObject:self.gender forKey:@"gender"];//    [aCoder encodeInteger:self.age forKey:@"age"];}//对person对象进行反归档时候,执行该方法//创建一个新的person对象,所有属性都是解码得到的- (id)initWithCoder:(NSCoder *)aDecoder{    self = [self init];    if (self) {        self.name = [aDecoder decodeObjectForKey:@"name"];        self.gender = [aDecoder decodeObjectForKey:@"gender"];        self.age = [aDecoder decodeIntegerForKey:@"age"];    }    return self;   }@end

在viewController中使用对象进行归档代码如下:

对象的归档
//对复杂的对象进行归档person=》NSData    Person * p = [[Person alloc] init];    p.name = @"kevin";    p.gender = @"male";    p.age = 25;    NSMutableData * data = [NSMutableData dataWithCapacity:40];    //创建归档工具对象    NSKeyedArchiver * archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];    [archiver encodeObject:p forKey:@"person"];//归档 这里面调用的就是nscoding的两个协议方法    [archiver finishEncoding];//归档结束    //将归档后的NSData,写入文件,存储在沙盒中    NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];    NSString * filePath = [documentPath stringByAppendingPathComponent:@"savePerson"];    [data writeToFile:filePath atomically:YES];
对象的解档
//根据文件路径读取data    NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];    NSString * filePath = [documentPath stringByAppendingPathComponent:@"savePerson"];    NSData * data = [NSData dataWithContentsOfFile:filePath];    //将Nsdata 通过反归档,转化成person对象    NSKeyedUnarchiver * unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];    //通过方归档得到复杂对象    Person * p = [unarchiver decodeObjectForKey:@"person"];    [unarchiver finishDecoding];    NSLog(@"name = %@",p.name);    NSLog(@"gender = %@",p.gender);    NSLog(@"age = %d",p.age);

看似一切都感觉还可以吧,挺顺利的。但是假如你这个复杂对象的属性有一两百个,是不是会感觉到整个人都不好呢,分析下,这种归档和解档明显是通过Object-c中KVC进行的存取,经过查阅资料可以使用objc/runtime+KVC实现

思路如下:
1. 动态获取这个类中所有的属性
2. 然后根据获取的属性字符利用KVC进行归档

废话少说上干活

#import<objc/runtime.h>Ivar *varA = class_copyIvarList([Person class],&count);for(int i = 0:i < count:i ++){    Ivar v = varA[i];    const char *name = ivar_getName(v);    NSLog(@"%s",name);    //你会看到它会将这个类中多有的属性以字符形式输入}

KVC取值

id value = [self valueForKey:strName];[encoder encodeObject:value forKey:strName];

在Person类的.m文件实现如下代码

归档如下

//归档- (void)encodeWithCoder:(NSCoder *)encoder{    unsigned int count;    Ivar *ivar = class_copyIvarList([Person 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);}@end

解档如下

//解档- (id)initWithCoder:(NSCoder *)decoder{    if (self = [super init]) {        unsigned int count = 0;        //获取类中所有成员变量名        Ivar *ivar = class_copyIvarList([Person 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);    }    return self;}

是不是瞬间感觉整个人好多了。O(∩_∩)O哈哈~

0 0