【IOS开发之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】书签管理器项目》书签管理器里面有书签。我们也可以使用归档来操作,我们只需要把书签管理器归档就可以了,书签自然就被归档进去了。

具体操作

我们要做的只有四步,如果不需要解归档,第四步的解归档可以不要。

第一步:增加一个<NSCoding>

在每个类的.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的一个特点,一定要注意流程。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-14 11:51:29

【IOS开发之Objective-C】数据持久化--文件和归档的相关文章

iOS开发之JSON格式数据的生成与解析

本文将从四个方面对IOS开发中JSON格式数据的生成与解析进行讲解: 一.JSON是什么? 二.我们为什么要用JSON格式的数据? 三.如何生成JSON格式的数据? 四.如何解析JSON格式的数据?  JSON格式取代了xml给网络传输带来了很大的便利,但是却没有了xml的一目了然,尤其是json数据很长的时候,我们会陷入繁琐复杂的数据节点查找中.这时我们就需要一款在线校验工具 BeJson. 一.JSON是什么? JSON(JavaScript Object Notation) 是一种轻量级的

iOS开发之 AES+Base64数据混合加密与解密

2016-04-08 09:03 编辑: liubinqww 分类:iOS开发 来源:liubinqww 投稿 4 889 "APP的数据安全已经牵动着我们开发者的心,简单的MD5/Base64等已经难以满足当下的数据安全标准,本文简单的介绍下AES与Base64的混合加密与解密" AES:高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES

iOS开发之AFNetworking实现数据传输和文件上传

//传输数据 1 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 2 manager.responseSerializer = [AFHTTPResponseSerializer serializer]; 3 manager.requestSerializer = [AFHTTPRequestSerializer serializer]; 4 5 //2.设置登录参数 6 NSDi

iOS开发之Socket通信实战--Request请求数据包编码模块

实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncSocket来进行长连接连接和传输数据,该第三方地 址:https://github.com/robbiehanson/CocoaAsyncSocket,读者可以自行google或者baidu搜索 这个库的用法,网上有很多资料,而且用法不难. 在一些对Socket通信使用需求不是很高的应用中,比如需要

iOS开发之 Xcode6 添加xib文件,去掉storyboard的hello world应用

iOS开发之  Xcode6.1创建仅xib文件,无storyboard的hello world应用 由于Xcode6之后,默认创建storyboard而非xib文件,而作为初学,了解xib的加载原理很重要,所以,需要创建一个没有storyboard的项目 1. 创建一个新的工程 2. 选择仅一个视图的模板 选择 Single View Application , 点击Next 3. 填写项目信息 不需要选择core data,填好信息后,点击next,然后点击create 4. 删除story

iOS开发之MVVM在项目中的应用

今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦~). 由于本人项目经验有限,关于架构设计方面的东西理解有限,我个人对MVVM的理解主要是借鉴于之前的用过的MVC的Web框架~在学校的时候用过ThinkPHP框架,和SSH框架,都是MVC的架构模式,今天MVVM与传统的MVC可谓是极为相似,也可以说是兄弟关系,也就是一家人了. 说到架构设计和团队

iOS开发之AFNetworking开源库的使用

iOS开发之AFNetworking开源库的使用 1.简介 常见的处理网络请求方式 (1)NSURLConnection/NSURLSession (2)ASIHttpRequest 早期项目中比较常见, 由于作者不更新了 (3)AFNetworking 推荐使用, 项目中使用 (4)MKNetworkKit 试试 2.配置和使用 2.1 配置 库文件拖入工程中, 包含头文件 #import "AFNetworking.h" 2.2 使用 //演示AFNetworking的使用 //1

【IOS开发之Objective-C】协议和代理

在现实生活中我们存在各种各样的协议,但是都有一个共同点,就是拟定的协议,就要遵守,不遵守就是违约.在OC中也有协议这一个概念而且和我们现实生活中的协议的特点是类似的.有时我们自己想做什么事,但是现在没这个能力自己去做,亲力亲为,我们就需要找代理来帮我们做了.那么在OC中也有代理这个概念.下面就简单的说说OC中的协议和代理. 一.协议 在<[IOS开发之Objective-C]对象的交互>中实现了一种对象的交互的方式.在OC中还有其他方式,比如说协议,在OC中用协议来规范接口,是实现对象之间的交

iOS开发之UILabel

UILabel是iOS开发中常用的一个组件,主要用来显示内容. UILabel的主要使用如下: ? 1 2 3 4 5 6 7 8 9 10 /*尺寸*/ CGRect labelRect = CGRectMake(100, 100, 80, 40); /*初始化*/ UILabel *titleLabel = [[UILabel alloc] initWithFrame:labelRect]; /*一些属性的设置*/ titleLabel.font = [UIFont systemFontOf