- 浏览: 26405 次
- 性别:
- 来自: 北京
最新评论
-
micallz:
绝知此事要躬行。
Git忽略文件(转载好文) -
lalakang:
提示找不到新项目的文件啊
ios如何在当前工程中添加编辑新建的FramesWork (两个ios工程联调同样适用 ) -
lalakang:
表示搞不对啊!!!
ios如何在当前工程中添加编辑新建的FramesWork (两个ios工程联调同样适用 )
摘自:infoq http://www.infoq.com/cn/articles/data-storage-in-ios
作者 高嘉峻 发布于 2013年3月27日
你是用什么方法来持久保存数据的?这是在几乎每一次关于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命令封装成对象和方法,可以供大家参考。大家可以在Githubhttps://github.com/gaosboy/SQLight上获取这个工程的代码进一步了解。
用CoreData规划应用中对象
官方给出的定义是,一个支持持久化的,对象图和生命周期的自动化管理方案。严格意义上说CoreData是一个管理方案,他的持久化可以通过SQLite、XML或二进制文件储存。如官方定义所说,CoreData的作用远远不止储存数据这么简单,它可以把整个应用中的对象建模并进行自动化的管理。
图4,官方文档中解释CoreData给出的对象图示例
正如上图所示,MyDocument是一个对象实例,有两个Collection:Employee和Department,存放各自的对象列表。MyDocument、Employee和Department三个对象以及他们之间的关系都通过CoreData建模,并可以通过save方法进行持久化。
从归档文件还原模型时CoreData并不是一次性把整个模型中的所有数据都载入内存,而是根据运行时状态,把被调用到的对象实例载入内存。框架会自动控制这个过程,从而达到控制内存消耗,避免浪费。
无论从设计原理还是使用方法上看,CoreData都比较复杂。因此,如果仅仅是考虑缓存数据这个需求,CoreData绝对不是一个优选方案。CoreData的使用场景在于:整个应用使用CoreData规划,把应用内的数据通过CoreData建模,完全基于CoreData架构应用。
苹果官方给出的一个示例代码http://developer.apple.com/library/ios/#samplecode/Locations/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008406,结构相对简单,可以帮助大家入门CoreData。
使用基本对象类型定制的个性化缓存方案
之前提到的NSUserDefaults和SQLite适合存储基础类型的小数据,而CoreData则不适合存储单一的数据,那么对于类似图片这种较大的数据要用什么方式储存呢?我给出的建议就是:自己实现一套存储方案。说到订制存储方案大家非常容易质疑,这是不是又在重新发明轮子。我可以非常明确的告诉大家,这绝不是在重新发明轮子。首先要明确,这个所谓的定制方案适用于互联网应用中对远程数据的缓存,几个限制条件缺一不可。
从需求出发分析缓存数据有哪些要求:按Key查找,快速读取,写入不影响正常操作,不浪费内存,支持归档。这些都是基本需求,那么再进一步或许还需要固定缓存项数量,支持队列缓存,缓存过期等。从这些需求入手设计一个缓存方案并不十分复杂,Kache是笔者根据开发应用的需求开发的一套缓存组件,通过分析Kache希望可以给大家一个思路。
图5,Kache架构图
如上图所示,Kache扮演的是一个典型缓存角色。应用加载远程数据生成应用数据对象的同时,通过Kache把数据缓存起来,再次请求则直接通过Kache获取数据。
缓存对象可以是NSDictionary、NSArray、NSSet或NSData这些可直接归档的类型,每个缓存对象对应一个Key。缓存对象包括数据和过期时间,内存中存放在一个单例字典中,闪存中每个对象存为一个文件。Key空间按照各种顺序存放缓存对象的Key集合,Pool为固定大小的数组,当数量达到上限,最早过期的一个Key将被删除,对应的缓存对象也被清除。Queue也是固定大小的数组,以先进先出的规则管理Key的增删。 每一次有新的缓存对象存入,自动检测Key空间中过期的集合并清除。
此外,控件提供save和load方法支持持久化和重新载入。
Kache最初设计为存放图片缓存,之后也曾用于缓存文本数据,由于使用了过期和归档相结合的逻辑,可以保证大部分命中的缓存对象都在内存中,从而获取了较高的效率。读者可以从Github上https://github.com/gaosboy/kache获取Kache源码了解更多。
以上介绍了几种iOS开发中经常会遇到的储存数据方法,从其存储原理、使用方式和适用场景几方面进行进了简单的对比。事实上每一款应用都很难采用一种单一的方案完成整个应用的数据储存任务,需要根据不同的数据类型,选择最合适的方案,以便整个应用获得良好的运行时性能。
作者简介:
高嘉峻(微博:@gaosboy),SegmentFault.com联合创始人,杭州iOS开发者沙龙发起人,资深iOS开发者。
作者 高嘉峻 发布于 2013年3月27日
你是用什么方法来持久保存数据的?这是在几乎每一次关于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命令封装成对象和方法,可以供大家参考。大家可以在Githubhttps://github.com/gaosboy/SQLight上获取这个工程的代码进一步了解。
用CoreData规划应用中对象
官方给出的定义是,一个支持持久化的,对象图和生命周期的自动化管理方案。严格意义上说CoreData是一个管理方案,他的持久化可以通过SQLite、XML或二进制文件储存。如官方定义所说,CoreData的作用远远不止储存数据这么简单,它可以把整个应用中的对象建模并进行自动化的管理。
图4,官方文档中解释CoreData给出的对象图示例
正如上图所示,MyDocument是一个对象实例,有两个Collection:Employee和Department,存放各自的对象列表。MyDocument、Employee和Department三个对象以及他们之间的关系都通过CoreData建模,并可以通过save方法进行持久化。
从归档文件还原模型时CoreData并不是一次性把整个模型中的所有数据都载入内存,而是根据运行时状态,把被调用到的对象实例载入内存。框架会自动控制这个过程,从而达到控制内存消耗,避免浪费。
无论从设计原理还是使用方法上看,CoreData都比较复杂。因此,如果仅仅是考虑缓存数据这个需求,CoreData绝对不是一个优选方案。CoreData的使用场景在于:整个应用使用CoreData规划,把应用内的数据通过CoreData建模,完全基于CoreData架构应用。
苹果官方给出的一个示例代码http://developer.apple.com/library/ios/#samplecode/Locations/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008406,结构相对简单,可以帮助大家入门CoreData。
使用基本对象类型定制的个性化缓存方案
之前提到的NSUserDefaults和SQLite适合存储基础类型的小数据,而CoreData则不适合存储单一的数据,那么对于类似图片这种较大的数据要用什么方式储存呢?我给出的建议就是:自己实现一套存储方案。说到订制存储方案大家非常容易质疑,这是不是又在重新发明轮子。我可以非常明确的告诉大家,这绝不是在重新发明轮子。首先要明确,这个所谓的定制方案适用于互联网应用中对远程数据的缓存,几个限制条件缺一不可。
从需求出发分析缓存数据有哪些要求:按Key查找,快速读取,写入不影响正常操作,不浪费内存,支持归档。这些都是基本需求,那么再进一步或许还需要固定缓存项数量,支持队列缓存,缓存过期等。从这些需求入手设计一个缓存方案并不十分复杂,Kache是笔者根据开发应用的需求开发的一套缓存组件,通过分析Kache希望可以给大家一个思路。
图5,Kache架构图
如上图所示,Kache扮演的是一个典型缓存角色。应用加载远程数据生成应用数据对象的同时,通过Kache把数据缓存起来,再次请求则直接通过Kache获取数据。
缓存对象可以是NSDictionary、NSArray、NSSet或NSData这些可直接归档的类型,每个缓存对象对应一个Key。缓存对象包括数据和过期时间,内存中存放在一个单例字典中,闪存中每个对象存为一个文件。Key空间按照各种顺序存放缓存对象的Key集合,Pool为固定大小的数组,当数量达到上限,最早过期的一个Key将被删除,对应的缓存对象也被清除。Queue也是固定大小的数组,以先进先出的规则管理Key的增删。 每一次有新的缓存对象存入,自动检测Key空间中过期的集合并清除。
此外,控件提供save和load方法支持持久化和重新载入。
Kache最初设计为存放图片缓存,之后也曾用于缓存文本数据,由于使用了过期和归档相结合的逻辑,可以保证大部分命中的缓存对象都在内存中,从而获取了较高的效率。读者可以从Github上https://github.com/gaosboy/kache获取Kache源码了解更多。
以上介绍了几种iOS开发中经常会遇到的储存数据方法,从其存储原理、使用方式和适用场景几方面进行进了简单的对比。事实上每一款应用都很难采用一种单一的方案完成整个应用的数据储存任务,需要根据不同的数据类型,选择最合适的方案,以便整个应用获得良好的运行时性能。
作者简介:
高嘉峻(微博:@gaosboy),SegmentFault.com联合创始人,杭州iOS开发者沙龙发起人,资深iOS开发者。
发表评论
-
xcode4.3下制作framework
2013-04-09 09:25 1992转自:xcode4.3下制作framework——(xc ... -
iOS网络组件对比:AFNetworking VS ASIHTTPRequest
2013-03-07 10:10 1536在开发iOS应用过程中, ... -
ios如何在当前工程中添加编辑新建的FramesWork (两个ios工程联调同样适用 )
2012-12-12 14:57 3173唐彬琪 可能很多大牛都见过FaceBook的three2 ... -
Xcode4快速Doxygen文档注释 — 简明图文教程
2012-12-03 17:28 1191转自:http://blog.chukong-inc.com/ ... -
如何让IOS应用从容地崩溃
2012-12-03 16:55 1116转自:http://blog.chukong-inc.c ... -
Git忽略文件(转载好文)
2012-11-21 11:29 1273摘自:http://cwind.iteye.com/bl ... -
git简明操作教程
2012-11-19 17:32 995摘自:https://www.akii.org/gi ... -
iOS开发细节记录汇总
2012-11-13 14:56 10861. 模拟器网速调整: 限制时输入下面两行,根据需要修 ... -
iOS签名总结
2012-11-13 11:34 1964摘自:http://www.devdiv.com/iOS签名总 ... -
iPhone开发资源汇总
2012-11-13 14:50 2159很多ios效果,以及控件集合 http://code4app. ... -
模拟器与真机下ffmpeg的编译方法(总结版)
2012-11-13 14:51 1436模拟器与真机下ffmpeg的编译方法(总结版) 编译f ... -
开源的电子书阅读器项目
2012-11-07 14:57 1876iphone平台上开源的电子书阅读器项目: https ... -
iOS高效开发必备的10款Objective-C类库
2012-11-07 14:28 750这里列出的库等功能使开发更容易。如果你是一个iOS开发人员,在 ... -
iOS6.0框架及功能更新小结
2012-11-07 14:58 794iOS6.0框架及功能更新小结 1. Maps 替换 ... -
const、static的理解
2012-11-07 14:58 1282对于C/C++语言来讲, const就是只读的意思,只在声明中 ... -
ios控件自定义指引
2012-11-07 14:58 1111转自:http://leakswww.devdiv ...
相关推荐
Core Data是Apple提供的一种数据管理框架,它不仅处理数据存储,还支持数据模型、关系和对象的生命周期管理。Core Data可以使用SQLite、Binary或In-Memory存储。以下是Core Data的基本使用步骤: - **设置数据模型*...
在iOS开发中,Block和代理是两种常用的回调机制,它们都可以用来实现对象间的通信,但具体用法和特性有所差异。下面将详细讲解Block和代理的对比,以及它们各自的应用场景。 首先,Block是一种内联函数,它可以捕获...
标题中的“iOS_Protobuf”指的是在iOS平台上应用Protocol Buffers(通常简称为Protobuf)这一...通过学习和实践这些知识点,开发者能够提升iOS应用的数据处理效率,尤其是在网络通信和数据存储方面,从而优化应用性能。
其中,钥匙串(Keychain)是Apple提供的一种安全、可靠的数据存储机制,尤其适用于存储敏感信息,如密码、证书、密钥和其他身份验证凭证。本教程将深入探讨iOS中的钥匙串服务以及如何使用它来替代传统的`...
书中会讲解如何使用UIKit框架来创建视图、处理用户交互,以及如何实现多任务、网络通信、数据存储等功能。此外,还可能涉及Core Data,苹果提供的对象关系映射框架,用于管理应用程序的数据模型。 本书还可能深入到...
【对比iOS和安卓Win8平板的十大优势】 在平板电脑市场上,苹果的iPad一直保持着显著的销售领先地位,而安卓平板和搭载Windows 8系统的平板也在不断追赶,尤其在商务和娱乐领域表现出色。Windows 8平板尽管销量不如...
MIUI是中国知名的手机操作系统,由小米公司开发,它以其丰富的自定义选项和...总的来说,"MIUI仿iOS1.zip"为MIUI用户提供了一种改变手机视觉风格的方式,让他们可以在享受MIUI强大功能的同时,体验到iOS的视觉美感。
在iOS开发中,AES(Advanced Encryption Standard)ECB(Electronic Codebook)加密是一种常见的数据安全保护技术。AES是国际标准的对称加密算法,而ECB是它的一种工作模式。本篇文章将深入探讨AES ECB加密在iOS开发...
7. **数据库存储**:介绍Core Data框架,学习如何在iOS应用中持久化数据。 8. **推送通知**:讲解如何集成Apple Push Notification服务,实现实时消息推送。 9. **多线程**:讨论GCD(Grand Central Dispatch)和...
在“一步一步学习+iOS+6编程(第四版)-项目源代码”这个压缩包中,包含的是针对初学者的iOS 6编程教程的实践项目源代码。这个资源旨在帮助开发者逐步理解并掌握iOS应用开发的基本技能和流程。以下是该资源涵盖的一些...
在iOS开发中,饼图(Pie Chart)是一种常见的数据可视化工具,它以圆形为基本图形,将整体数据分割成多个扇形部分,每个扇形代表一个分类或比例,直观地展示各部分占总体的大小关系。这个“ios-饼图.zip”文件很可能...
#### 七、Objective-C数据类型与C语言数据类型对比 - **Objective-C数据类型**: - `NSString` - `NSNumber` - `NSArray` - `NSMutableArray` - `NSData` - 这些都是类,创建后成为对象。 - **C语言数据类型**:...
相比SQLite3,CoreData提供了更高层次的抽象,使得开发者能够更便捷地处理数据模型、对象关系以及数据存储。本篇文章将详细介绍CoreData的使用方法,并对比其与SQLite3的区别,以展示其优势。 首先,让我们了解...
书中可能会对比这两种语言,解释它们的基本语法、面向对象特性以及如何创建和管理对象。 2. **Xcode IDE**:Apple的集成开发环境(IDE)Xcode是iOS开发的首选工具,它包含了编写、测试和调试代码所需的所有功能。...
1. **Objective-C与Swift**: 本书会对比讲解这两种iOS开发的主要语言,Objective-C是苹果早期的首选语言,而Swift是近年来推出的现代化替代品,更加安全、简洁和高效。 2. **Xcode IDE**: Xcode是iOS应用开发的核心...
在iOS应用开发中,本地数据存储是不可或缺的一部分。SQLite和CoreData是两种常见的本地数据库解决方案。SQLite是一个轻量级的关系型数据库,而CoreData则是Apple提供的一种对象图管理和持久化框架。下面我们将深入...
云端服务方面,Google的云端服务如Gmail、Google Drive和Google Photos等与Android深度整合,提供无缝的数据同步和存储解决方案。相比之下,Apple的iCloud服务在Apple设备间同步效果良好,但跨平台兼容性不如Google...
在iOS开发中,如果你需要处理媒体文件,如播放、编辑或转码,FFmpeg是一个不可或缺的库。 FFmpeg的核心组件包括: 1. **libavcodec**:这是FFmpeg的编码库,提供了大量的音频和视频编码器,能够将原始音视频数据...
CRC32(Cyclic Redundancy Check,循环冗余校验)是一种广泛应用于数据通信和存储中的错误检测方法,主要用于确保数据在传输或存储过程中的完整性。在iOS开发中,CRC32同样扮演着重要角色,尤其是在文件传输、数据...
2. **MVC(Model-View-Controller)设计模式**:iOS应用通常遵循MVC架构,这是一种组织代码的方式,将数据模型、用户界面和控制逻辑分离。分析源码可以理解如何在实践中实现这一模式,以及它如何帮助保持代码的清晰...