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: 572064792 | Nodejs:329118122 做人要厚道,转载请注明出处!
















本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sunshine-anycall/p/3446606.html ,如需转载请自行联系原作者

相关文章
|
1月前
|
搜索推荐 数据管理 定位技术
iOS应用开发中有多种主流框架
iOS应用开发中有多种主流框架
180 60
|
1月前
|
Android开发 Swift iOS开发
深入探索iOS与Android操作系统的架构差异及其对应用开发的影响
在当今数字化时代,移动设备已经成为我们日常生活和工作不可或缺的一部分。其中,iOS和Android作为全球最流行的两大移动操作系统,各自拥有独特的系统架构和设计理念。本文将深入探讨iOS与Android的系统架构差异,并分析这些差异如何影响应用开发者的开发策略和用户体验设计。通过对两者的比较,我们可以更好地理解它们各自的优势和局限性,从而为开发者提供有价值的见解,帮助他们在这两个平台上开发出更高效、更符合用户需求的应用。
|
2月前
|
Android开发 Swift iOS开发
iOS和安卓作为主流操作系统,开发者需了解两者差异以提高效率并确保优质用户体验。
【10月更文挑战第1天】随着移动互联网的发展,智能手机成为生活必需品,iOS和安卓作为主流操作系统,各有庞大的用户群。开发者需了解两者差异以提高效率并确保优质用户体验。iOS使用Swift或Objective-C开发,强调简洁直观的设计;安卓则采用Java或Kotlin,注重层次与动画。Swift和Kotlin均有现代编程特性。此外,iOS设备更易优化,而安卓需考虑更多兼容性问题。iOS应用仅能通过App Store发布,审核严格;安卓除Google Play外还可通过第三方市场发布,审核较宽松。开发者应根据需求选择合适平台,提供最佳应用体验。
75 3
|
1月前
|
开发框架 前端开发 Android开发
探索安卓和iOS应用开发中的跨平台解决方案
【10月更文挑战第42天】在移动应用开发的广阔天地中,安卓和iOS系统如同两座巍峨的山峰,分别占据着半壁江山。开发者们在这两座山峰之间穿梭,努力寻找一种既能节省资源又能提高效率的跨平台开发方案。本文将带你走进跨平台开发的世界,探讨各种解决方案的优势与局限,并分享一些实用的代码示例,助你在应用开发的道路上更加游刃有余。
|
1月前
|
Android开发 Swift iOS开发
探索iOS与安卓应用开发的差异性
探索iOS与安卓应用开发的差异性
49 2
|
2月前
|
Java Android开发 Swift
掌握安卓与iOS应用开发:技术比较与选择指南
在移动应用开发领域,谷歌的安卓和苹果的iOS系统无疑是两大巨头。它们不仅塑造了智能手机市场,还影响了开发者的日常决策。本文深入探讨了安卓与iOS平台的技术差异、开发环境及工具、以及市场表现和用户基础。通过对比分析,旨在为开发者提供实用的指导,帮助他们根据项目需求、预算限制和性能要求,做出最合适的平台选择。无论是追求高度定制的用户体验,还是期望快速进入市场,本文都将为您的开发旅程提供有价值的见解。
|
2月前
|
物联网 vr&ar Android开发
掌握安卓与iOS应用开发:核心技术与未来趋势
本文深入探讨了安卓和iOS应用开发的核心技术,包括开发环境、主要编程语言、常用框架以及性能优化技巧。同时,文章还展望了两大平台未来的发展趋势,如人工智能、增强现实和物联网的集成,为开发者提供全面的技术参考和发展指引。
|
2月前
|
安全 Android开发 iOS开发
深入解析:安卓与iOS的系统架构及其对应用开发的影响
本文旨在探讨安卓与iOS两大主流操作系统的架构差异,并分析这些差异如何影响应用开发的策略和实践。通过对比两者的设计哲学、安全机制、开发环境及性能优化等方面,本文揭示了各自的特点和优势,为开发者在选择平台和制定开发计划时提供参考依据。
67 4
|
1月前
|
开发工具 Android开发 Swift
探索iOS与安卓应用开发的异同点
【10月更文挑战第24天】本文通过比较iOS和安卓开发环境,旨在揭示两大移动平台在开发过程中的相似性与差异性。我们将探讨开发工具、编程语言、用户界面设计、性能优化及市场分布等方面,以期为开发者提供全面的视角。通过深入浅出的分析,文章将帮助读者更好地理解每个平台的独特之处及其对应用开发的影响。
|
3月前
|
开发工具 Android开发 iOS开发
掌握安卓与iOS应用开发:关键技术与未来展望
本文深入探讨了安卓和iOS平台下的应用开发技术,重点比较了两大平台的架构、开发工具和市场策略。通过分析最新的技术趋势和开发者社区的反馈,文章为读者提供了一个全面的对比视角,旨在帮助开发者做出更明智的平台选择和开发决策。