iOS 序列化与反序列化
2014-01-14 17:51
330 查看
研究了一下 NSKeyedArchiver 和 NSKeyedUnarchiver ,其中遇到了一个麻烦的问题,研究许久才找到问题,在此留念吧!
概述:
1. 序列化是iOS数据持久化中的一种方式,其他的方式包括plist 文件, 数据库, NSUserDefaults 等,而序列化相对于其他几种方式的的优点是它可以持久化对象,或者说类。
2. 如果对象是NSString, NSDictionary , NSArray , NSData, NSNumber 等类型,可以直接使用NSKeyedArchiver 进行归档和NSKeyedUnarchiver 进行恢复;
3. 不是所有的对象都可以使用这种方法,只有遵守了NSCoding 协议的对象才可以,NScoding 的协议有两个,分别是:
encodeWithCoder: 每次归档对象时,都会调相应的这个方法,在这个方法里指定如果归档对象中的每个实力变量,可以使用encodeObjec:forKey: 方法归档其中的实例变量;
initWithCoder: 每次从文件中恢复对象时,都会调用这个方法,在这个方法中指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey: 方法解码实例变量;
下面是具体的测试代码:
//viewController.m
//对象中的NSCoding 协议的实现
// ArchiverDataModel.h
暂时就先测试这么多,以后用到得时候在继续完善!!!
概述:
1. 序列化是iOS数据持久化中的一种方式,其他的方式包括plist 文件, 数据库, NSUserDefaults 等,而序列化相对于其他几种方式的的优点是它可以持久化对象,或者说类。
2. 如果对象是NSString, NSDictionary , NSArray , NSData, NSNumber 等类型,可以直接使用NSKeyedArchiver 进行归档和NSKeyedUnarchiver 进行恢复;
3. 不是所有的对象都可以使用这种方法,只有遵守了NSCoding 协议的对象才可以,NScoding 的协议有两个,分别是:
encodeWithCoder: 每次归档对象时,都会调相应的这个方法,在这个方法里指定如果归档对象中的每个实力变量,可以使用encodeObjec:forKey: 方法归档其中的实例变量;
initWithCoder: 每次从文件中恢复对象时,都会调用这个方法,在这个方法中指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey: 方法解码实例变量;
下面是具体的测试代码:
//viewController.m
#import "ViewController.h" #import "ArchiverDataModel.h" @interface ViewController ()<NSKeyedArchiverDelegate,NSKeyedUnarchiverDelegate>{ NSMutableArray *_array; } @property (retain, nonatomic) ArchiverDataModel *dataModel; @end @implementation ViewController @synthesize dataModel; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)addButtonFrame:(CGRect)frame title:(NSString *)title selecter:(SEL)selecter{ UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; button.frame = frame; [button setTitle:title forState:UIControlStateNormal]; [button addTarget:self action:selecter forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor grayColor]; [self addButtonFrame:CGRectMake(100, 100, 120, 40) title:@"归档" selecter:@selector(archiver:)]; [self addButtonFrame:CGRectMake(100, 200, 120, 40) title:@"解档" selecter:@selector(unArchiver:)]; self.dataModel.name = @"123"; self.dataModel.age = 123; _array = [[NSMutableArray alloc]initWithArray:@[@"1",@"2",@"3"]]; } - (void)archiver:(UIButton *)button{ /* 普通变量的序列化 NSString *filePath = @"/Users/tongkun/Desktop/archiver.archiv"; NSMutableData *data = [[NSMutableData alloc]init]; NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data]; [archiver encodeObject:self.dataModel forKey:@"dataModel"]; [archiver encodeObject:_array forKey:@"array"]; [archiver encodeInt:10 forKey:@"int"]; [archiver finishEncoding]; BOOL ret = [data writeToFile:filePath atomically:YES]; NSLog(@"ret: %d",ret); */ NSString *filePath = @"/Users/tongkun/Desktop/archiver.archiv"; //扩展名可以随便取 NSMutableData *data = [[NSMutableData alloc]init]; NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data]; archiver.delegate = self; ArchiverDataModel *model = [[ArchiverDataModel alloc]init]; model.name = @"name"; model.age = 1; [archiver encodeObject:model forKey:@"dataModel"]; /* 此处我尝试用ArchiverDataModel 作为self的属性进行归档,归档也能成功,但是并不调用对象类中的encodeWithCoder:方法, 但是文件恢复(解码)不出来,也并没有调用对象类中的initWithCoder: 方法,暂时没找到解决办法,所以只能创建一个独立的ArchiverDataModel变量进行测试了 */ [archiver finishEncoding]; BOOL ret = [data writeToFile:filePath atomically:YES]; NSLog(@"ret: %d",ret); } - (void)unArchiver:(UIButton *)button{ /* 普通的归档的恢复 NSString *filePath = @"Users/tongkun/Desktop/archiver.archiv"; NSData *data = [NSData dataWithContentsOfFile:filePath]; NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data]; NSArray *array = [unarchiver decodeObjectForKey:@"array"]; int i = (int)[unarchiver decodeObjectForKey:@"int"]; NSLog(@"array: %@, i: %d",array, i); */ NSString *filePath = @"/Users/tongkun/Desktop/archiver.archiv"; NSData *data = [NSData dataWithContentsOfFile:filePath]; NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data]; unarchiver.delegate = self; ArchiverDataModel *model = [unarchiver decodeObjectForKey:@"dataModel"]; [unarchiver finishDecoding]; NSLog(@"model.name : %@, model.age : %ld",model.name, model.age); } #pragma -mark #pragma -mark NSKeyedArchiver / NSKeyedUnarchiver Delegate - (void)archiverDidFinish:(NSKeyedArchiver *)archiver{ NSLog(@"archiverDidFinish"); } - (void)unarchiverDidFinish:(NSKeyedUnarchiver *)unarchiver{ NSLog(@"unarchiverDidFinish"); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
//对象中的NSCoding 协议的实现
// ArchiverDataModel.h
#import "ArchiverDataModel.h" @implementation ArchiverDataModel @synthesize name; @synthesize age; - (void)encodeWithCoder:(NSCoder *)aCoder{ [super encodeWithCoder:aCoder]; //如果父类也实现NSCoding 协议则应该写这句 [aCoder encodeObject:name forKey:@"name"]; [aCoder encodeInteger:age forKey:@"age"]; } //对属性解码,解归档调用 - (id)initWithCoder:(NSCoder *)aDecoder{ self = [super init]; if (self) { self.name = [aDecoder decodeObjectForKey:@"name"]; self.age = [aDecoder decodeIntegerForKey:@"age"]; } return self; } @end
暂时就先测试这么多,以后用到得时候在继续完善!!!
相关文章推荐
- iOS中复杂实体类对象的json序列化
- ios序列化高效压缩70%
- ios-day21-02(ios开发之json数据的解析(json的反序列化))
- NScoder / NScoding (iOS对象序列化与反序列化)
- iOS&nbsp;序列化与反序列化
- ios序列化
- Use GraceNote SDK in iOS(一)通过序列化GDO查询专辑封面
- iOS开发笔记--序列化 NSKeyedArchiver,NSPropertyListSerialization
- ios writeToFile 和 对象序列化
- iOS数据存取和对象序列化
- iOS开发之功能模块--本地序列化
- Use GraceNote SDK in iOS(一)通过序列化的GDO查询专辑封面
- IOS 归档 即序列化与反序列化
- iOS NSKeyedArchiver序列化后进行数据持久化(swift)
- iOS开发网络篇 一一 AFN序列化、监测网络状态
- ios 序列化保存bean数据。
- IOS 之对象序列化
- ios开发系列之对象的序列化与反序列化
- IOS序列化/反序列化
- IOS 反射获取属性,序列化成xml