在iOS开发过程中,很多时候都需要进行一些数据的储存和读入,在数据量不大的情况下,使用plist储存数据是一种很方便的方式,但是plist只能允许储存一些系统自带的数据类型,如果需要储存自定义的数据类型,plist是是用不了的,但是可以使用另外一种数据持久化的方法-对象归档。
NSCoding协议
要想使用对象归档,需要归档的对象就要实现NSCoding协议,实现NSCoding协议需要实现它的两个方法:
- (void)encodeWithCoder:(NSCoder *)aCoder;//写入数据
- (id)initWithCoder:(NSCoder *)aDecoder;//读取数据
我们可以将对象的属性写入NSCoder对象中,也可以从其中读取写入的数据,NSCoder中包含了许多方法,其中:
- (void)encodeObject:(id)objv forKey:(NSString *)key;
- (void)encodeBool:(BOOL)boolv forKey:(NSString *)key;
- (void)encodeInt:(int)intv forKey:(NSString *)key;
- (void)encodeInt32:(int32_t)intv forKey:(NSString *)key;
- (void)encodeInt64:(int64_t)intv forKey:(NSString *)key;
- (void)encodeFloat:(float)realv forKey:(NSString *)key;
- (void)encodeDouble:(double)realv forKey:(NSString *)key;
可以将各种类型的对象写入到NSCoder对象中,并将其与key关联起来,而:
- (id)decodeObjectForKey:(NSString *)key;
- (BOOL)decodeBoolForKey:(NSString *)key;
- (int)decodeIntForKey:(NSString *)key;
- (int32_t)decodeInt32ForKey:(NSString *)key;
- (int64_t)decodeInt64ForKey:(NSString *)key;
- (float)decodeFloatForKey:(NSString *)key;
- (double)decodeDoubleForKey:(NSString *)key;
则可以将NSCoder中的对象使用key读取出来。
对象归档
而归档对象,需要使用
[NSKeyedArchiver archiveRootObject:object toFile:path];
将object对象归档到path文件中。逆归档则需要使用
[NSKeyedUnarchiver unarchiveObjectWithFile:path];
将path文件中的对象读取出来。
基本的对象归档流程就是这样,之后是我的一个示例:
//StudentModel.h
#import <Foundation/Foundation.h>
@interface StudentModel : NSObject <NSCoding>
@property (nonatomic, strong) NSString* name;
@property (nonatomic, strong) NSString* stuID;
@property (nonatomic, assign) NSInteger age;
@end
//StudentModel.m
#import "StudentModel.h"
@implementation StudentModel
#pragma mark -- NSCoding
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.stuID = [aDecoder decodeObjectForKey:@"stuID"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.stuID forKey:@"stuID"];
[aCoder encodeInteger:self.age forKey:@"age"];
}
@end
//ViewController.m
#import "ViewController.h"
#import "StudentModel.h"
@interface ViewController ()
{
StudentModel* _myStudent;
StudentModel* _myStudent1;
NSString* _path;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *Path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
_path = [Path stringByAppendingPathComponent:@"test"];
_myStudent = [[StudentModel alloc] init];
_myStudent.name = @"小明";
_myStudent.stuID = @"20121001047";
_myStudent.age = 21;
[self archivedStudent];
}
#pragma mark -- response
- (IBAction)touchUnarchiveBtn:(id)sender {
[self unarchivedStudent];
}
#pragma mark -- method
- (void)archivedStudent
{
[NSKeyedArchiver archiveRootObject:_myStudent toFile:_path];
}
- (void)unarchivedStudent
{
_myStudent1 = [NSKeyedUnarchiver unarchiveObjectWithFile:_path];
NSLog(@"name:%@", _myStudent1.name);
NSLog(@"studentID:%@", _myStudent1.stuID);
NSLog(@"age:%d", (int)_myStudent1.age);
}
@end
附上打印结果:
2015-07-26 09:04:06.163 NSCodingTest[7679:7139551] name:小明
2015-07-26 09:04:06.164 NSCodingTest[7679:7139551] studentID:20121001047
2015-07-26 09:04:06.165 NSCodingTest[7679:7139551] age:21