(一一五)利用NSKeyedArchiver实现任意对象转为二进制

【应用背景】

在数据库中存储数据时,如果对象过于复杂,又不必要创建复杂的表,可以直接把整个对象转化为二进制存入数据库字段,然后取出后再还原即可。

【实现方法】

在PHP中,使用序列化和反序列化可以实现这样的功能。

在OC中,使用NSKeyedArchiver和NSKedUnarchiver可以实现对象转二进制和二进制转对象,要实现转化,必须遵循NSCoding协议,并且实现encodeWithCoder方法用来转化数据为二进制,实现initWithCoder实现二进制数据还原成类对象,OC的常见类,例如数组、字典等已经实现了这些内容,直接转换即可,如果是自己定义的类,需要手动实现。

下面以将自定义的Person类转化为二进制存储,然后再读取出来的过程,来加深对这个功能的理解。

【具体案例】

①定义Peron类,有三个属性,如下,注意要遵循NSCoding协议。

#import <Foundation/Foundation.h>

@interface Person : NSObject <NSCoding>

@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, assign) double height;

@end
②实现编码和解码的方法,并且重写description方法方便打印类内数据。

注意:encode和decode时要选择合适的数据类型

#import "Person.h"

@implementation Person

- (void)encodeWithCoder:(NSCoder *)encoder{
    
    [encoder encodeObject:self.name forKey:@"name"];
    [encoder encodeInteger:self.age forKey:@"age"];
    [encoder encodeDouble:self.height forKey:@"height"];
    
}

- (id)initWithCoder:(NSCoder *)decoder{
    
    if (self = [super init]) {
        
        self.name = [decoder decodeObjectForKey:@"name"];
        self.age = [decoder decodeIntegerForKey:@"age"];
        self.height = [decoder decodeDoubleForKey:@"height"];
    }
    
    return self;
    
}

- (NSString *)description{
    
    return [NSString stringWithFormat:@"%@ %ld %lf",_name,_age,_height];
    
}

@end
③随机生成一些Person对象,使用NSKeyedArchiver进行二进制转换,然后存入文件,注意到因为对象放到了数组里,因此对象不需要主动转化为二进制,这个过程会自动完成,注意一定要实现上面的decode和encode方法

NSMutableArray *persons = [NSMutableArray array];
for (int i = 0; i < 100; i++) {
    Person *p = [[Person alloc] init];
    p.name = [NSString stringWithFormat:@"<%05d>",arc4random_uniform(10000)];
    p.age = arc4random_uniform(100);
    p.height = 1.5 + arc4random_uniform(60) / 100.0;
    [persons addObject:p];
}
[NSKeyedArchiver archiveRootObject:persons toFile:@"/Users/soulghost/Desktop/persons.data"];
④读取文件,使用NSKeydUnarchiver进行还原,在还原数组时,数组内的数据也被自动还原
NSMutableArray *persons = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/soulghost/Desktop/persons.data"];
NSLog(@"%@",persons);
由于重写了description方法,类的内容会规范的打印如下:

    "<07060> 10 1.960000",
    "<05393> 35 1.960000",
    "<01438> 68 1.920000",
    "<00835> 40 1.710000",
    "<00035> 14 1.780000",
    "<08394> 66 1.910000",
    "<00504> 29 1.580000",
    "<03072> 4 1.900000",
    "<00473> 7 1.800000",
    "<04528> 10 1.790000",
    "<05930> 3 1.790000",
    "<07390> 2 1.590000",
    "<00820> 62 1.670000",
    ...

通过这么一个简单的案例,就能学会任意对象和二进制对转的方法,这个方法能够跨越不同语言间的类定义不同而实现统一的数据存储,能够轻松实现类的数据库存储。

posted on 2015-08-10 22:32  张大大123  阅读(185)  评论(0编辑  收藏  举报

导航