详解iOS的数据存储

2020-01-15 17:38:27于海丽

不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的的对象才可以.

NSCoding协议有2个方法:

.encodeWithCoder:

每次归档对象时,都会调用这个方法.一般在这个方法里面指定如何归档对象中的每个实例变量.可以使用:encodeObject:forkey:方法归档实例变量.

.initWithCoder:
每次从文件中恢复(解码)对象时,都会调用这个方法.一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forkey方法解码实例变量.

归档一个NSArray对象到Documents/array.archive :


NSString *path = [NSString stringWithFormat:@"Documents/array.archive"];
NSArray *array = [NSArray arrayWithObjects:@"a",@"b",nil];
[NSKeyedArchiver archiveRootObject:array toFile:path];

恢复(解码)NSArray对象


 NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

NSKeyedArchiver-归档Person对象:

Person.h中:


@interface Person : NSObject <NSCoding>
@property(nonatomic,copy) NSString *name;
@property(nonatomic,assign) int age;
@property(nonatomic,assign) float height;@end

Person.m中:


 @implementation Person
-(void)encodeWithCoder:(NSCoder*)encoder{  
 [encoder encodeObject:self.name forKey:@"name"];  
 [encoder encodeInt:self.age forKey:@"age"];  
 [encoder encodeFloat:self.height forKey:@"height"];
}
-(id)initWithCoder:(NSCoder*)decoder {  
 self.name= [decoder decodeObjectForKey:@"name"];  
 self.age= [decoder decodeIntForKey:@"age"];  
 self.height= [decoder decodeFloatForKey:@"height"];  
 return self;
}

 // 归档(编码)
 Person *person = [[Person alloc] init];
 person.name = @"JN";
 person.age = 22;
 person.height = 1.63f;
 [NSKeyedArchiver archiveRootObject:person toFile:path];

 // 恢复(解码)
 Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
@end

NSKeyedArchiver-归档对象的注意

如果父类也遵守了NSCoding协议,请注意:

1.应该在uencodeWithCoder:方法中加上一句 [super encodeWithCode:encode];确保继承的实例变量也能被编码,即也能被归档.

2.应该在initWithCoder:方法中加上一句 self = [super initWithCoder:decoder];确保继承的实例变量也能被解码,即也能被恢复.

NSData

使用archiveRootObject:toFile:方法可以将一个对象直接写入到一个文件中,但有时候可能想将多个对象写入到同一个文件中,那么就要使用NSData来进行归档对象.

NSData可以为一些数据提供临时的存储空间,以便随后写入文件,或者存放从磁盘读取的文件内容.可以使用[NSMutableData data]创建可变数据空间.