iOS应用开发之Persistence持久化[转]

简介:

持久化(Persistence)

持久化(Persistence)意思就是当你退出app的时候它还会存在。NSUserDefaults就是一个非常简单的持久化方案,不过这有限制,它只能是很小的东西,通常是些用户选项。

如何把那些大数据的东西持久化?

第一个方法,把东西持久化的第一个简单的方式有点像用NSUserDefaults里的property list来实现的进化版,property list是我们自定义的一个概念,是NSArray、NSDictionary、NSNumber、NSString、 NSDate和NSData的组合。所有以上这些都有API可以用来保存,NSUserDefaults也有些API可以。

NSData、NSArray和NSDictionary里还有很重要的方法writeToURL:atomically:,这个方法就是把一个array写到一个文件系统中URL表示的地方,atomically就是如果文件已经存在,它会把文件移到一边,然后写到一个新的文件,关掉这个新的文件。实际上就是写到一个临时命名的文件,然后关掉,把另一个移走,有点原子化操作的感觉,不能写到一半就停下来。writeToURL之后,为了把东西取回来,可以用initWithContentsOfURL或者dataWithContentsOfURL。这些读写方法,不管是发送到NSData或者NSArray或者NSDictionary,就是想让一个相同类型的对象去读回来,它的内部可以就是些property list的东西。

还有另一个类叫做NSPropertyListSerialization,它所做的事情就是把property list转化成NSData,反之亦然。这样它可以将property list转化成一堆二进制数,然后就可以写到磁盘上,或储存到网络。也可以通过网络读取一堆二进制数再通过NSPropertyListSerialization把它们转化回property list。

关于存储的另外一个方法就是通过对象的映像图(arbitrary graphs)来进行归档对象(Archiving Objects)的保存。

把东西存储到文件系统当中。

然后是SQLite

关于持久化存储的重头部分就是Core Data,这是在SQL上层的一个面向对象的数据库机制。

Archiving

在做对象图归档的时候有很多陷阱,归档很适合做循环图。Archiving能发现指针实际所指的对象或者指针相互指着,然后当unarchives的时候又恢复那个指针。但你要考虑清楚来使你构建的对象图有意义,最好的例子可能是在xcode里面建立的view层级。

当从对象库中拖一些东西到屏幕上,就是在实例化UIView,实例化UIViewController,它们都是generic的,所以才需要去inspector面板来改变它们的类。

基本上就是在这个图里面的对象都必须实现NSCoding这个protocol,然后这个protocol里面有两个重要方法:

- (void)encodeWithCoder:(NSCoder *)coder; 
- initWithCoder:(NSCoder *)coder;

第一个是把自己放进archive,第二是把你从archive中取出来用的。这就是viewController出现在storyboard时不用调用它们的指定初始化的原因,因为它们用了这套初始化。这套归档系统在对它们做alloc initWithCoder,因为它们之前用encodeWithCoder把自己保存起来了。在UIView里没有调用initWithFrame,而是用frame对应的encodeWithCoder和initWithCoder来代替。

- (void)encodeWithCoder:(NSCoder *)coder { 
     [super encodeWithCoder:coder]; 
     [coder encodeFloat:scale forKey:@“scale”]; 
     [coder encodeCGPoint:origin forKey:@“origin”]; 
     [coder encodeObject:expression forKey:@“expression”];
}

必须保证initWithCoder和encodeWithCoder是相对应的。

复制代码
- initWithCoder:(NSCoder *)coder { 
     self = [super initWithCoder:coder]; 
     scale = [coder decodeFloatForKey:@“scale”]; 
     expression = [coder decodeObjectForKey:@“expression”]; 
     origin=[coderdecodeCGPointForKey:@“origin”]; //notethatorderdoesnotmatter
}
复制代码

怎么来实现这些呢?NSKeyedArchiver中的类方法:

+ (NSData *)archivedDataWithRootObject:(id <NSCoder>)rootObject;

可以传递一个根对象,比如在storyboard里面的根对象就可能是顶层的view controller。你要做的就是确保里面所有的对象都实现NSCoder协议。

NSKeyedUnarchiver中的类方法:

+ (id <NSCoder>)unarchiveObjectWithData:(NSData *)data;

这正好相反,你提供一个已经归档的NSData,然后返回被encode的根对象。

id <NSCoder> object = ...; 
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object]; 
id <NSCoder> dup = [NSKeyedArchiver unarchiveObjectWithData:data];

如果有一个对象,通过第二行将得到关于这个对象的NSData。

如果encode一个view使它的super view被归档,你会被拒绝,除非它处于正确的层级,如果它在顶部它会被拒绝,但如果在内部,就会执行。

File System

ios是基于Unix的,底层都是Unix的文件系统,这里有文件系统保护,不可能看到所有的东西,而且也不能随意的写入。

只能在sandbox中做写入,为什么?为了安全。当在设备上删除app时,也会删除所有相关的数据。通过在sandbox中进行写操作,所有应用程序的东西不管是用户创建的还是应用程序自己在sandbox里面创建的一旦移除,所有的都会被移除。

sandbox到底是什么?这里面有应用程序的bundle目录,应用程序不是单独的大的二进制文件,它实际上是一个目录,里面有可执行程序、二进制文件、storyboard及拖进来的图片,所有东西都在里面,这就是应用程序的bundle。sandbox里的目录本身是不可写的,不能在目录里写入东西。这基本上就是一个用xcode创建的app的只读副本。documents目录是sandbox中的一个重要目录,这些地方是用来存储那些被用户视为是自己的文档的。还有一个缓存目录,这里都是一些我们写出来的东西,用户一般不会认为这些是文档,而且这些文档的存在都很短暂,没有了也不会影响到用户。documentation里的关键东西是NSSearchPathDirectory。

如何才能得到这些目录,如何得到这些目录的URL?如果想在application目录中写入,但又不能写入,那么要做的就是将application包里面的东西拷贝到sandbox中任意一个可写的地方然后在那里写入。如果你想将一个数据库连接到你的app,或写入那些数据库,得将它们拷贝出来,无论是拷到文档目录,或是缓存目录,总之是可以写入了。

如何搞到这些目录的路径呢?使用这个方法:

- (NSArray *)URLsForDirectory:(NSSearchPathDirectory)directory    
                    inDomains:(NSSearchPathDomainMask)domainMask; //NSUserDomainMask

NSURL中有个API可以获得一个URL的清单,但得传入想要的目录类型,譬如文档目录、缓存目录。以上方法和NSURL的方法,它们返回一个路径的array,所以当我请求缓存目录时,将得到一个URL的array,或是路径字符串的数组。

NSFileManager为文件系统提供实用操作,这不是用来读写它们自身文件的类。你可以用它来找出文件到底有多大,删除那些陈旧的需要被踢出的缓存文件,也可以用它来找出譬如当应用程序启动时,缓存里面都有哪些文件。它是线程安全的,只要不在两个不同的线程中使用同一个实例。

NSString也有一些文件系统有关的东西,特别是制作路径,一般用NSURL来指定一个链接,有时会用字符串来构建URL。

- (NSString *)stringByAppendingPathComponent:(NSString *)component;

这可以在一个路径中添加内容。还可以把字符串的内容写到文件里去,必须要指定用哪种编码,譬如ASCII、ISOLatin1,

- (BOOL)writeToFile:(NSString *)path
         atomically:(BOOL)flag 
           encoding:(NSStringEncoding)encoding //e.g.ASCII,ISOLatin1,etc.
              error:(NSError **)error;

也可以从文件读取string:

- (NSString *)stringWithContentsOfFile:(NSString *)path
                          usedEncoding:(NSStringEncoding *)encoding 
error:(NSError **)error;

SQLite

SQLite是指SQL文件保存在单一一个文件里,存储在一个单一的文件中,它速度很快,只占用很小的内存。它基于事务处理,是真正的SQL。这不是基于服务器的SQL,而是基于文件的,所以它是并发性的。如果app中有两个线程,都要写入到SQL数据库中,这可以正常运行。但它只是做简单的锁线程和并发。

以下就是它的API:

复制代码
复制代码
intsqlite3_open(constchar*filename,sqlite3**db); //get a database into db 
int sqlite3_exec(sqlite3 *db,    // execute SQL statements
                 const char *sql, 
                 int (*callback)(void *, int, char **, char **), 
                 void *context, 
                 char **error);
int mycallback(void *context,int count,char **values,char **cols); //data returned 
int sqlite3_close(sqlite3 *db);    // close the database
复制代码
复制代码

当你打开SQL文件时,你会得到一个SQL数据库指针,然后要执行SQL语句。向数据库递交你的SQL语句,一些SQL语句就会回调然后在一张表中将你请求的数据返回给你,返回的也可能是error。回调函数通常是这样的格式:

int mycallback(void *context,int count,char **values,char **cols);

然后就可以关闭了。你要做的就是第三行const char *sql,这是执行SQL语句的地方。

 

from:http://www.cnblogs.com/geory/archive/2013/03/11/2953294.html

欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 330987132 | Go:217696290 | Python:336880185 | 做人要厚道,转载请注明出处!http://www.cnblogs.com/sunshine-anycall/p/3446606.html
相关文章
|
存储 SQL 数据库
【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记46 Persistence持久化
本话将介绍IOS中的四种数据持久化方式: Archiving SQLite File System Core Data 前面我们将结果NSUsrDefaults的用法,它是针对小数据量的持久化技术,本话的四种方式是针对大数据量的操作。
977 0
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
11月前
|
iOS开发 开发者
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
671 67
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
|
10月前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
414 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
iOS开发 开发者 MacOS
深入探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】 本文将带领读者深入了解Apple最新推出的SwiftUI框架,这一革命性的用户界面构建工具为iOS开发者提供了一种声明式、高效且直观的方式来创建复杂的用户界面。通过分析SwiftUI的核心概念、主要特性以及在实际项目中的应用示例,我们将展示如何利用SwiftUI简化UI代码,提高开发效率,并保持应用程序的高性能和响应性。无论你是iOS开发的新手还是有经验的开发者,本文都将为你提供宝贵的见解和实用的指导。
340 66
|
10月前
|
人工智能 程序员 API
iOS|记一名 iOS 开发新手的前两次 App 审核经历
啥,这玩意也有新手保护期?
301 0
|
12月前
|
存储 监控 API
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
1227 11
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
366 3
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。