ios序列化与反序列化,本地化 -凯发k8官方网
2019独角兽企业重金招聘python工程师标准>>>
你是用什么方法来持久保存数据的?这是在几乎每一次关于ios技术的交流或讨论都会被提到的问题,而且大家对这个问题的热情持续高涨。本文主要从概念上把“数据存储”这个问题进行剖析,并且结合各自特点和适用场景给大家提供一个选择的思路,并不详细介绍某一种方式的技术细节。
谈到数据储存,首先要明确区分两个概念,数据结构和储存方式。所谓数据结构就是数据存在的形式。除了基本的nsdictionary、nsarray和nsset这些对象,还有更复杂的如:关系模型、对象图和属性列表多种结构。而存储方式则简单的分为两种:内存与闪存。内存存储是临时的,运行时有效的,但效率高,而闪存则是一种持久化存储,但产生i/o消耗,效率相对低。把内存数据转移到闪存中进行持久化的操作称成为归档。
二者结合起来才是完整的数据存储方案,我们最常谈起的那些:sqlite、coredata、nsuserdefaults等都是数据存储方案。当然在这些框架提供的方案之外,我们自己也可以按照个性化需求订制方案。这些存储方案侧重不同,支持的形式和方式也各不相同,在不同的使用场景下表现也是各有优劣。但万变不离其宗,无论什么方案都可以用下图来解释。
图1,存储方案示意图
以下将对四种存储方式进行详细的介绍:
nsuserdefaults,用于存储配置信息
sqlite,用于存储查询需求较多的数据
coredata,用于规划应用中的对象
使用基本对象类型定制的个性化缓存方案
用nsuserdefaults存储配置信息
nsuserdefaults被设计用来存储设备和应用的配置信息,它通过一个工厂方法返回默认的、也是最常用到的实例对象。这个对象中储存了系统中用户的配置信息,开发者可以通过这个实例对象对这些已有的信息进行修改,也可以按照自己的需求创建新的配置项。
图2,笔者手机中[nsuserdefaults standarduserdefaults]内容
nsuserdefaults把配置信息以字典的形式组织起来,支持字典的项包括:字符串或者是数组,除此之外还支持数字等基本格式。一句话概括就是:基础类型的小数据的字典。操作方法几乎与nsdictionary的操作方法无异,另外还可以通过指定返回类型的方法获取到指定类型的返回值。
图3,nsuserdefaults提供的指定返回类型的方法列表
nsuserdefaults的所有数据都放在内存里,因此操作速度很快,并还提供一个归档方法: (void)synchronize。开发者自定义的配置项(如图2中的最后一项 key:alkdjfkladsjfmm)会以plist格式的文件归档在相应应用目录的/library/preferences/[app_bundle_identifier].plist文件。再次初始化获得实例对象后,框架会把用户自定义的这个配置和系统配置合并得到完整数据。
用sqlite存储查询需求较多的数据
ios的sdk里预置了sqlite的库,开发者可以自建sqlite数据库。sqlite每次写入数据都会产生io消耗,把数据归档到相应的文件。
sqlite擅长处理的数据类型其实与nsuserdefaults差不多,也是基础类型的小数据,只是从组织形式上不同。开发者可以以关系型数据库的方式组织数据,使用sql dml来管理数据。 一般来说应用中的格式化的文本类数据可以存放在数据库中,尤其是类似聊天记录、timeline等这些具有条件查询和排序需求的数据。
每一个数据库的句柄都会在内存中都会被分配一段缓存,用于提高查询效率。另一个方面,由于查询缓存,当产生大量句柄或数据量较大时,会出现缓存过大,造成内存浪费。
sqlite的使用起来要比nsuserdefaults复杂的多,因此建议开发者使用sqlite要搭配一个操作控件使用,可以简化操作。笔者开发的sqlight是一款对sqlite操作的封装,把相对复杂的sqlite命令封装成对象和方法,可以供大家参考。大家可以在github上获取这个工程的代码进一步了解。
用coredata规划应用中对象
官方给出的定义是,一个支持持久化的,对象图和生命周期的自动化管理方案。严格意义上说coredata是一个管理方案,他的持久化可以通过sqlite、xml或二进制文件储存。如官方定义所说,coredata的作用远远不止储存数据这么简单,它可以把整个应用中的对象建模并进行自动化的管理。
图4,官方文档中解释coredata给出的对象图示例
正如上图所示,mydocument是一个对象实例,有两个collection:employee和department,存放各自的对象列表。mydocument、employee和department三个对象以及他们之间的关系都通过coredata建模,并可以通过save方法进行持久化。
从归档文件还原模型时coredata并不是一次性把整个模型中的所有数据都载入内存,而是根据运行时状态,把被调用到的对象实例载入内存。框架会自动控制这个过程,从而达到控制内存消耗,避免浪费。
无论从设计原理还是使用方法上看,coredata都比较复杂。因此,如果仅仅是考虑缓存数据这个需求,coredata绝对不是一个优选方案。coredata的使用场景在于:整个应用使用coredata规划,把应用内的数据通过coredata建模,完全基于coredata架构应用。
苹果官方给出的一个示例代码,结构相对简单,可以帮助大家入门coredata。
obj-c中有一类对象:nsarray,nsdictionary,nsstring,nsnumber,nsdate,nsdata以及它们的可变版本(指nsmutablearray,nsmutabledictionary...这一类) ,都可以方便的将自身的数据以某种格式(比如xml格式)序列化后保存成本地文件。
示例代码:nsarraytest.h
#import运行结果:nsarraytest.m
2011-03-03 14:20:01.501 plist[1246:a0f] (
one,
two,
three
)
如果查看/tmp/data.txt,能看到下面的内容:
即nsarray默认是以xml格式来序列化对象的.
如果你用来存放数据的类是自己定义的,并不是上面这些预置的对象,那么就要借助正式协议nscoding来实现序列化和反序列化。
比如,我们有一个自己的类sample.h
#import这里我们定义几个不同类型的属性,有字符串,有整数,有浮点数,还有一个可变长的数组对象
sample.m
#import "sample.h"@implementation sample@synthesize name; @synthesize magicnumber; @synthesize shoesize; @synthesize subthingies;-(id) initwithname:(nsstring *)n magicnumber:(int)m shoesize:(float)ss {if (self=[super init]){self.name = n;self.magicnumber = m;self.shoesize = ss;self.subthingies = [nsmutablearray array];}return (self); }-(void) dealloc {[name release];[subthingies release];[super dealloc]; }//将对象编码(即:序列化) -(void) encodewithcoder:(nscoder *)acoder {[acoder encodeobject:name forkey:@"name"];[acoder encodeint:magicnumber forkey:@"magicnumber"];[acoder encodefloat:shoesize forkey:@"shoesize"];[acoder encodeobject:subthingies forkey:@"subthingies"]; }//将对象解码(反序列化) -(id) initwithcoder:(nscoder *)adecoder {if (self=[super init]){self.name = [adecoder decodeobjectforkey:@"name"];self.magicnumber = [adecoder decodeintforkey:@"magicnumber"];self.shoesize = [adecoder decodefloatforkey:@"shoesize"];self.subthingies = [adecoder decodeobjectforkey:@"subthingies"];}return (self);}-(nsstring*) description {nsstring *description = [nsstring stringwithformat:@"%@:%d/%.1f %@",name,magicnumber,shoesize,subthingies];return (description); }@end注意其中的:encodewithcoder与initwithcoder,这是nscoding协议中定义的二个方法,用来实现对象的编码与解码。其实现也不复杂,利用的是key-value的经典哈希结构。当然一般在编码中,对于key的名字字符串,建议用define以常量方式事先定义好,以避免开发人员字符串键入错误。
测试一下:
#import运行结果:
2011-03-03 14:36:48.540 plist[1322:a0f] thing1:42/10.5 (
1,
2
)
2011-03-03 14:36:48.548 plist[1322:a0f] thing1:42/10.5 (
1,
2
)
查看/tmp/data.txt,能看到以下内容:
由于经过了编码,里面的内容没有象前面的nsarray那样可读性强。
有关序列化和反序列化内容转自如下地址:
http://www.cnblogs.com/yjmyzz/archive/2011/03/03/1969859.html
转载于:https://my.oschina.net/sayonala/blog/305624
总结
以上是凯发k8官方网为你收集整理的ios序列化与反序列化,本地化的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇:
- 下一篇: asp.net上传图片文件自动修改图片大