标签:objective-c 文件 归档 解归档 数据持久化
在OC中数据持久化的方式有多种,例如:写入一个文件再或是归档。写入文件的方式我们一般都可以直接读取文件中的数据。比如我把数据写进一个XX.txt文档里面。只有数据写入成功了我就可以直接读取这个文件了。但是这样对于一些用户关键的数据并不能起到保密的作用,如果需要保密还需要使用归档操作。
//首先声明一个字符串 NSString * str1 = @"123456789";
直接使用方法:
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFileencoding:(NSStringEncoding)enc error:(NSError **)error;
把一个OC的字符串写入一个txt文件中:
[str1 writeToFile:@"/Users/文件路径保密/str1.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];//先把字符串转换为二进制的数据流再写入到文件中。
先调用方法
- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding;把OC字符串转换为二进制数据流,
再调用方法
- (BOOL)writeToFile:(NSString *)pathatomically:(BOOL)useAuxiliaryFile;把二进制流的数据写入文件中。
NSData * data2 = [str1 dataUsingEncoding:NSUTF8StringEncoding]; //字符串转数据流 [data2 writeToFile:@"/Users/文件路径保密/data2.txt" atomically:YES];
上述两种写入文件的数据都是最后可以直接在生产的str1.txt和data2.txt文档读取的。在目标路径中找到它,就像我们点开普通的的txt文档一样打开它就可以看见了,其实它也就是一个普通的txt文档。这就是最后的效果。
深拷贝和浅拷贝。
第一种解释:像retain一样,只是对象的引用计数的加1(只是指针的拷贝),这种叫浅拷贝。像copy一样产生一个新的对象,这种叫深拷贝。
第二种解释:只是拷贝这个对象,没有拷贝对象的子对象,这种叫浅拷贝。既拷贝对象,也拷贝了它的子对象,这种叫深拷贝。
归档是一种深拷贝。
在《【IOS开发之Objective-C】书签管理器项目》书签管理器里面有书签。我们也可以使用归档来操作,我们只需要把书签管理器归档就可以了,书签自然就被归档进去了。
我们要做的只有四步,如果不需要解归档,第四步的解归档可以不要。
在每个类的.h文件中:@interfaceBookMark : NSObject <NSCoding>
在NSObject 后面增加一个 <NSCoding>。
在每个类的.m文件中:
重写一个解归档的方法:- (id)initWithCoder:(NSCoder *)aDecoder 和一个归档方法:
- (void)encodeWithCoder:(NSCoder *)aCoder 。这个两个方法名是固定,也不需要我们自己调用;因为在归档和解归档的时候系统会自动调用,我们只需要重写一下就可以了。怎么实现这两个方法呢?
在书签BookMark中我们做这些操作。
//解归档 我们需要解归档什么诗句在里面写什么 - (id)initWithCoder:(NSCoder *)aDecoder{ self = [super init]; if (self) { _url = [aDecoder decodeObjectForKey:@"网址"]; _title = [aDecoder decodeObjectForKey:@"标题"]; _stars = [aDecoder decodeIntegerForKey:@"星级"]; _vist = [aDecoder decodeIntegerForKey:@"访问量"]; _lev = [aDecoder decodeObjectForKey:@"权限"]; } return self; } //归档 我们需要归档什么就在里面写什么 - (void)encodeWithCoder:(NSCoder *)aCoder{ [aCoder encodeObject:_url forKey:@"网址"]; [aCoder encodeObject:_title forKey:@"标题"]; [aCoder encodeInteger:_stars forKey:@"星级"]; [aCoder encodeInteger:_vist forKey:@"访问量"]; [aCoder encodeObject:_lev forKey:@"权限"]; }
在书签管理器BookManager中我们也做类似的操作,我就不写在.h文件中说怎么操作了,直接看.m文件中的实现了。
//解归档 - (id)initWithCoder:(NSCoder *)aDecoder{ self = [super init]; if (self) { _array = [aDecoder decodeObjectForKey:@"管理器"]; } return self; } //归档 - (void)encodeWithCoder:(NSCoder *)aCoder{ [aCoder encodeObject:_array forKey:@"管理器"]; }
在上述解归档和归档中有这么两个方法:
- (id)decodeObjectForKey:(NSString *)key; - (void)encodeObject:(id)objv forKey:(NSString *)key;
是不是有点像是字典的操作呢。注意关键词forKey。在他后面的字符串我们可以随便写,但是要保证方法之间key的对应关系和方法内key的区分。
在实现归档操作之前,我们需要新增件几个书签,我们还是使用《【IOS开发之Objective-C】书签管理器项目》中介绍的的方法增加的三个书签:
//新建一个百度的书签 BookManager * myBookManager = [[BookManager alloc] init]; [myBookManageraddBookMarkWithUrl:@"www.baidu.com" withTitle:@"百度" withStars:3 withVist:123 withLevel:@"C"]; //新建一个新浪的书签 [myBookManageraddBookMarkWithUrl:@"www.sina.com" withTitle:@"新浪" withStars:7 withVist:456 withLevel:@"C"]; //新建一个搜狐的书签 [myBookManageraddBookMarkWithUrl:@"www.souhu.com" withTitle:@"搜狐" withStars:5 withVist:756 withLevel:@"C"];
有了这三个书签作为一个例子就可以来具体实现归档了。
NSMutableData * data1 = [[NSMutableData alloc] init]; NSKeyedArchiver * arc1 = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data1]; /*归档*/ [arc1encodeObject:myBookManager forKey:@"书签管理器"]; [arc1finishEncoding]; //封口 这一步一定在写入数据之前 [data1writeToFile:@"/Users/文件路径保密/书签类设计.txt" atomically:YES];
这里使用到了两个类:NSMutableData 和 NSKeyedArchiver。一个是先声明一个可变的数据流,一个是新建一个归档的实例。有了上述操作,其实归档已经操作完了。最后会生成一个《书签类设计.txt》的文档,但是我们却打不开它。下面这个图也证实了,里面是有内容的,但是不能像上面的文件操作那样直接看到是什么内容,而且还打不开。
有了归档操作后数据可以写入一个文件实现持久化了,而且还是保密的。但是我们看不见数据啊。难道写入的数据就不能再看见了?显然还有解归档的操作,在上面已经有了解归档这个词了。
解归档的操作其实很简单,上面在.m文件实现的两个解档的方法- (id)initWithCoder:(NSCoder *)aDecoder 就能发挥他们的作用了。
NSData * data2 = [[NSData alloc] initWithContentsOfFile:@"/Users/文件路径保密/书签类设计.txt"]; NSKeyedUnarchiver * uarc1 = [[NSKeyedUnarchiver alloc] initForReadingWithData:data2]; /*解归档*/ BookManager * bk1 = [uarc1 decodeObjectForKey:@"书签管理器"]; [uarc1finishDecoding]; [bk1showAllBookMark];
①. 声明一个数据流data2来接收刚才写入《书签类设计.txt》里面的数据;
②. 解归档,使用了一个和归档相对应的类NSKeyedUnarchiver;
③. 使用一个BookManager * bk1 的对象来接收解档“书签管理器”;
④. 完成解档;
⑤. 打印解档出来的数据。
打印结果:
2015-08-02 10:45:14.750 3.书签管理器[896:303] 网址:www.baidu.com 标题:百度 星级:3 访问量:123 权限:C 2015-08-02 10:45:14.752 3.书签管理器[896:303] 网址:www.sina.com 标题:新浪 星级:7 访问量:456 权限:C 2015-08-02 10:45:14.753 3.书签管理器[896:303] 网址:www.souhu.com 标题:搜狐 星级:5 访问量:756 权限:C
至此,归档和解归档的操作都介绍完了,其实实现起来并不困难。
在上面介绍深拷贝和浅拷贝的时候有这么一句话:既拷贝对象,也拷贝了它的子对象,这种叫深拷贝。归档是一种深拷贝。
在上面的例子中,我们归档的是书签管理器这个对象,不是书签。在书签管理器里面有三个书签对象:分别是百度、新浪和搜狐。这三个书签对象是书签管理器的一个子对象(不是继承关系)。也就是说我们不仅拷贝了书签管理器,还拷贝了书签管理器里面的子对象--书签。
在这篇中我们介绍了文件和归档、解归档的一些基本操作。在这些操作中我们不难发现这些操作的基本步骤都是相对固定的。我们只需要按照这个步骤调用方法就可以实现需要的功能,达到目的。这也是OC的一个特点,一定要注意流程。
版权声明:本文为博主原创文章,未经博主允许不得转载。
【IOS开发之Objective-C】数据持久化--文件和归档
标签:objective-c 文件 归档 解归档 数据持久化
原文地址:http://blog.csdn.net/zhuming3834/article/details/47205993