iOS数据存储之对象归档

对象归档

对象归档是iOS中数据持久化的一种方式。
归档是指另一种形式的序列化,但它是任何对象都可以实现的更常规的类型。使用对模型对象进行归档的技术可以轻松将复杂的对象写入文件,然后再从中读取它们。对象归档后将得到一个后缀为.archive的文件

要使用对象归档,则归档的对象所属类中实现的每个属性都是标量,或者都是遵循NSCoding协议和NSCopying协议的某个类的实例,也就是说,在类的头文件中需要添加如下语句
可以编解码的条件是:对象要实现<>中的两个协议,也就是说 要定义自己的编解码规则,在头文件中声明遵循下列两个协议

@interface BIDFourLines : NSObject <NSCoding, NSCopying>

遵循NSCoding协议

NSCoding中声明了两个方法,其中一个用于将对象编码到归档中,另一个方法对归档解码来创建一个新对象。
归档时要实现的方法为:

-(void)encodeWithCoder:(NSCoder *)aCoder;

可以使用KVC(Key-Value Coding,键值编码)对对象和原生数据类型进行编码和解码。
若要对对象进行归档,必须使用正确的编码方法将所有实例变量编码成encoder。
在解码时,实现一个通过NSCoder解码的对象初始化方法,就可以恢复之前归档的对象。解码时要实现的方法为:

-(id)initWithCoder:(NSCoder *)aDecode;

总的来说,只要对象实现了上面提到的两个方法,就可以对所有对象的属性进行编码和解码,然后就可以对对象进行归档,并且可以将其写入归档或者从归档中读取它们。

实现NSCopying协议

除了要遵循NSCoding协议外,还要求要使用归档的类实现NSCoping协议。这个协议中有一个copywithZone方法,

- (id)copyWithZone:(NSZone *)zone;

用来复制对象。其实现与inetWitheCoder非常相似,只需创建一个同一类的新实例,然后将新实例的所有属性都设置为与该对象属性相同的值。

案例

还是用之前那个案例来熟悉整个对象归档机制
首先仍然是获取应用的Documents文件夹,然后在该文件夹下创建一个归档文件,代码如下:

- (NSString *)dataFilePath
{
NSArray *paths = NSSearchPathForDirectoriesInDomain
( NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:@"data.archive"];
}

实现编码:
定义了一个用于编码的键,并且是常量

static NSString * const kRootKey = @"kRootKey";
//实现编码,定义自己的翻译规则,用kLinesKey来对lines进行编码
- (void)encodeWithCoder:(NSCoder *)aCoder;
{
[aCoder encodeObject:self.lines forKey:kLinesKey];
}

实现了编码后,就可以对对象进行归档了,对象归档发生在程序从前台退出之后。
具体的归档代码如下:

- (void)applicationWillResignActive:(NSNotification *)notification
{
//获取归档文件路径
NSString *filePath = [self dataFilePath]; //把文本框组中的数据读取出来,放进lines中
BIDFourLines *fourLines = [[BIDFourLines alloc] init];
fourLines.lines = [self.lineFields valueForKey:@"text"]; //声明一个二进制流 data,开辟了一个空间
NSMutableData *data = [[NSMutableData alloc] init];
//声明一个归档类,把归档类的内容放入data中
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]
initForWritingWithMutableData:data]; //用kRootKey进行编码
[archiver encodeObject:fourLines forKey:kRootKey]; //结束编码
[archiver finishEncoding]; //编码结束后,归档类的内容已经放入data中了,此时data仍然驻留在内存中,需要写入文件中
[data writeToFile:filePath atomically:YES];
}

实现解码:

//实现解码
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init]; if (self) {
self.lines = [aDecoder decodeObjectForKey:kLinesKey];
}
return self;
}

实现解码后,就能够对对象取消归档,这个过程发生在程序重新加载的时候,具体代码如下:

- (void)viewDidLoad
{
[super viewDidLoad];
//查找归档文件路径
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { //用归档文件中的数据初始化data
NSData *data = [[NSMutableData alloc]
initWithContentsOfFile:filePath]; //声明一个解归档对象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] //把data中的数据复制给解归档对象 initForReadingWithData:data]; //用kRootKey进行解码
BIDFourLines *fourLines = [unarchiver decodeObjectForKey:kRootKey]; //结束解码
[unarchiver finishDecoding]; //把lines中的数据填入到显示的文本框中
for (int i = 0; i < 4; i++) {
UITextField *theField = self.lineFields[i];
theField.text = fourLines.lines[i];
}
} //订阅消息,观察自身是否退到后台,若从前台退出,则运行applicationWillResigneActive方法,进行归档
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(applicationWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:app];
}

结果

归档后,将在应用的Documents文件夹下生成data.archive文件,如下图

用Notepad++打开该文件会看到一堆乱码,如下图:

总结

我感觉对象归档方法有点类似于加密,要对某个对象归档,首先要定义一套对象的编码机制,而这个编码机制就可理解为“加密”,而对对象取消归档的时候,我们用对应的解码机制来操作,也就是说,解码机制就是与“加密”对应的“解密”。也可以把编码和解码理解为一套“翻译规则”,在对象归档阶段,编译器按照用户定义的“翻译规则”将对象的各种属性翻译成底层的数据形式,在对象取消归档阶段,编译器又按照用户定义的“翻译规则”将之前保存的数据“翻译”回有意义的数据。对象归档可以层层嵌套,也就是说,对象可以包含一个自定义的对象,只要被包含的这个对象也遵循NSCoding和NSCopying协议,有了这个嵌套,我们就可以把相对复杂的对象保存起来。
从本质上看,对象归档是以文件的形式保存数据的,使用的时候到相应路径下去读取文件内容就可以了。归档后的数据文件是保密的,无法直接查看,而属性列表是明文,是可以直接查看的。

iOS数据存储之对象归档的更多相关文章

  1. IOS 数据存储(NSKeyedArchiver 归档篇)

    什么是归档 当遇到有结构有组织的数据时,比如字典,数组,自定义的对象等在存储时需要转换为字节流NSData类型数据,再通过写入文件来进行存储. 归档的作用 之前将数据存储到本地,只能是字符串.数组.字 ...

  2. iOS数据存储之属性列表理解

    iOS数据存储之属性列表理解 数据存储简介 数据存储,即数据持久化,是指以何种方式保存应用程序的数据. 我的理解是,开发了一款应用之后,应用在内存中运行时会产生很多数据,这些数据在程序运行时和程序一起 ...

  3. iOS数据存储类型 及 堆(heap)和栈(stack)

    iOS数据存储类型 及 堆(heap)和栈(stack) 一般认为在c中分为这几个存储区: 1栈 --  由编译器自动分配释放. 2堆 --  一般由程序员分配释放,若程序员不释放,程序结束时可能由O ...

  4. ios数据存储——对象归档

    归档:数据从内存与闪存相互转化,类似“序列化”,将数据转换成二进制字节数据 操作:有两种方式,第一种是单个对象作为root进行归档和恢复,一个对象一个文件:第二种,可以同时归档多个对象到一个文件 注意 ...

  5. IOS数据存储之归档/解档

    前言: 前天学习了NSUserDefaults,我们知道NSUserDefaults不能保存自定义对象,所以我们今天来认识一下归档(NSKeyedArchiver)和解档(NSKeyedUnarchi ...

  6. IOS数据存储之Sqlite数据库

    前言: 之前学习了数据存储的NSUserDefaults,归档和解档,沙盒文件存储,但是对于数据量比较大,需要频繁查询,删除,更新等操作的时候无论从效率上还是性能上,上述三种明显不能满足我们的日常开发 ...

  7. 读写应用程序数据-NSUserDefault、对象归档(NSKeyedArchiver)、文件操作

    ios中数据持久化存储方式一般有5种:NSUserDefault.对象归档(NSKeyedArchiver).文件操作.数据库存储(SQLite3).CoreData. 1.NSUserDefault ...

  8. iOS数据存储

    [reference]http://www.infoq.com/cn/articles/data-storage-in-ios 谈到数据储存,首先要明确区分两个概念,数据结构和储存方式.所谓数据结构就 ...

  9. 最全的iOS数据存储方法

    目的 项目准备运用的Core Data进行本地数据存储,本来打算只写一下Core Data的,不过既然说到了数据存储,干脆来个数据存储基础大总结!本文将对以下几个模块进行叙述. 沙盒 Plist Pr ...

随机推荐

  1. [codility]CountDiv

    https://codility.com/demo/take-sample-test/count_div 此题比较简单,是在O(1)时间里求区间[A,B]里面能被K整除的数字,那么就计算一下就能得到. ...

  2. ibatis动态查询

    在复杂查询过程中,我们常常需要根据用户的选择决定查询条件,这里发生变化的并不只是SQL 中的参数,包括Select 语句中所包括的字段和限定条件,都可能发生变化.典型情况,如在一个复杂的组合查询页面, ...

  3. IDEA快速光标跳转

    Ace Jump是一种从emacs上借鉴过来的快速光标跳转方式,操作方式是:你用某个快捷键进入Ace Jump模式后,再按任一个键,当前屏幕中所有该字符都被打上一个字母标记,你只要按这个字母,光标就会 ...

  4. AutoCAD图形打印出图片 C#

    这几天搞cad二次开发,用的是C#语言,目前在网上找到的资料比较少.弄了两天,才做出怎样实现打印出图片.首先得在AutoCAD软件界面下,设置打印机的页面设置和打印机设备名称一样(以防打印不出来).即 ...

  5. shell编程基础(2)---&&与||

    shell 编程重要的应用就是管理系统,对于管理系统中成千上万的程序而言,查询某个文件名是否存在,并且获取该文件名所指代文件基本信息是系统管理员的基本任务.shell命令可以很轻松的完成这项任务. # ...

  6. JDBC学习总结(一)

    1.JDBC概述     JDBC是一种可以执行SQL语句并可返回结果的Java API,其全称是Java DataBase Connectivity,也是一套面向对象的应用程序接口API,它由一组用 ...

  7. 利用 java.lang.Runtime.addShutdownHook() 钩子程序,保证java程序安全退出

    以前在开发时只知道依靠数据库事务来保证程序关闭时数据的完整性. 但有些时候一个业务上要求的原子操作,不一定只包括数据库,比如外部接口或者消息队列.此时数据库事务就无能为力了. 这时我们可以依靠java ...

  8. 人脸识别必读的N篇文章

    一,人脸检测/跟踪 人脸检测/跟踪的目的是在图像/视频中找到各个人脸所在的位置和大小:对于跟踪而言,还需要确定帧间不同人脸间的对应关系. 1, Robust Real-time Object Dete ...

  9. 经典K线组合图解 > 正文

    日K线波段中上下影线的箱体操作法(完整) http://video.sina.com.cn/v/b/130809461-2486130757.html!!经典K线组合图解 > 正文 http:/ ...

  10. 自动化:Appium运行成功,取得一个小的胜利

    看过乙醇大神的博文,然后又看了一些大神的博文,自己陆陆续续的折腾了一个月,今天上午的时候,appium终于跑起来了.纪念下,在自动化路上取得的一个小胜利 Appium版本:1.2 Python版本:2 ...