求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
ios开发之数据的持久化存储机制
 

作者:倾城一屁 ,发布于2012-8-14

 

IOS中数据的持久化保存这块内容,类似于Android中文件的几种常见的存储方式。

对于数据的持久化存储,ios中一般提供了4种不同的机制。

1.属性列表

2.对象归档

3.数据库存储(SQLite3)

4.苹果公司提供的持久性工具Core Data。

其实储存的形式无非就这么几种,而我们还必须要关心的是,这些文件会被放置在那个文件下,然后如何读取。 也就是说:IOS上数据存储,我们要了解的两点,数据存储格式(也就是存储机制),数据存储位置。

1》文件如何存储(如上面4点)

2》文件存储在哪里。

对于数据的操作,其实我们关心的是操作的速率。

就好比在Adnroid中偏好存储,数据库存储,io存储一样。

我大致问了我们公司新来的ios哥们,他说他们培训机构基本对数据操作这块就讲了属性列表和数据库,以及普通的文件存储(比如音视频图这些多媒体数据)。

我就只好先看看书了。

一:应用文件目录

首先我们来看了解下ios数据存储位置,因为只有知道位置路径我们才能去读取数据,而数据的持久化机制不过是针对操作速率来考虑的, 比如我们大致知道属性列表(既键值对形式)的存储熟虑应该高于数据库高于io文件流存储。

我们在选择用何种机制存储数据,主要也是看数据的形式。

一个ios应用安装后大致会有如下文件夹及其对应路径:

在mac上看模拟器中应用路径:

/Users/nono/Library/Application Support/iPhone Simulator/5.1/Applications/2D135859-1E80-4754-B36D-34A53C521DE3

你在finder中的home下可能找不到Library这个目录,因为貌似是影藏起来了(我这机器上是,在终端可以看到)。

最后那一窜的类似序列号的东西就是ios自动给应用生成的一组应用唯一识别码最为了应用的home目录名。

其下面就是上图所示了。

书上对这些文件夹介绍:

Document:应用程序将其数据存储在这个文件夹下,基于NSUserDefaults的首选项的设置除外。

简单理解是,基本上我们要操作的一些数据都是存储在这个文件夹下面的

TIPS:这边提下一点,对于ios系统这么分配文件夹,是因为在设备进行同步时,ITunes有选择性的意识来备份文件。

比如我们可以猜到,tmp下的应该就不会备份了。

对于Document文件夹目录路径的获取,API提供了这么一种方法:

[cpp] view plaincopy

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *docPath = [paths objectAtIndex:0];

Library:基于NSUserDefault首选项设置存储在其下Preferences文件夹中,简单来说,这个文件夹一般你很少操作到。

书上对于这部分基本没介绍。估计对于初级部分是跳过了。

Tmp:应用临时存储文件,当不需要时,应用负责删除其下的文件数据。

该文件也提供了目录获取方法:

Java代码

1.- (void)encodeWithCoder:(NSCoder *)aCoder    
2.{   //encoder    
3.    [aCoder encodeObject:stringAforKey:@"1"];    
4.    [aCoder encodeObject:stringBforKey:@"2"];    
5.}    
6.- (id)initWithCoder:(NSCoder *)aDecoder    
7.{    
8.    //decoder    
9.    if (self = [superinit]) {    
10.        stringA = [[aDecoder decodeObjectForKey:@"1"] retain];    
11.        stringB = [[aDecoder decodeObjectForKey:@"2"] retain];    
12.    }    
13.    returnself;    
14.}    
15.    
16.#pragma NSCopying协议实现    
17.- (id)copyWithZone:(NSZone *)zone    
18.{    
19.    TestObj *copy = [[[selfclass] allocWithZone:zone] init];    
20.    copy.stringA = [[self.stringAcopyWithZone:zone] autorelease];    
21.    copy.stringB = [[self.stringBcopyWithZone:zone] autorelease];    
22.    return copy;    
23.}    
24.@end   

然后是对对象归档的读取和写入

[cpp] view plaincopy 
//读取归档文件  
   NSData *data = [[NSMutableDataalloc] initWithContentsOfFile:myFile];  
   NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiveralloc] initForReadingWithData:data]; 
    TestObj * test = [unarchiver decodeObjectForKey:@"data"];  
   [unarchiver finishDecoding];  
   [data release];  
   [unarchiver release];  
     
   //写入归档文件  
   NSMutableData *data1 = [[NSMutableDataalloc] init];  
   NSKeyedArchiver *archiver = [[NSKeyedArchiveralloc] initForWritingWithMutableData:data1]; 
    [archiver encodeObject:test forKey:@"data"];  
   [archiver finishEncoding];  
   [data writeToFile:myFile atomically:YES];  
   [data1 release];  
   [archiver release];  
   [test release];  

但是问了下新同事,据说这个用到也是蛮少,至少他目前。

但是,我看了下,觉得这个和Android 中Parcelable 太尼玛像似了

三.数据库存储

和Android一样,ios中也是用了SQLite3这种嵌入式数据库。

这个网上例子是很多了。我这边就大致看下了数据库的打开, 数据库表创建,查询,插入

[cpp] view plaincopy 
//数据库操作  
sqlite3 *database;  
// const NSString * dbname = @"mydb"  
int result;  
//打开一个指定路径的现有的数据库,如果没有则会新建一个db库  
result =  sqlite3_open([myFile UTF8String], &database);  
if (result != SQLITE_OK) {  
     sqlite3_close(database);  
}  
   
//创建一个db表  
char *errorMsg;  
NSString *sql_create_table = @"CREATE TABLE IF NOT EXISTS NONOTABLE 省略~~~~~~~~~~~~~"; 
 int result1 ;  

//sqlite_exec用了针对sqlite3运行任何不要返回数据的命令,它用于执行更新,插入和删除。简单来说,这个方法执行的都是一些无需返回数据(虽然我们可能获取一个状态值。)。

result1 = sqlite3_exec(database, [sql_create_table UTF8String], NULL, NULL, &errorMsg); 
    
//检索查询操作  
int result2 ;  
sqlite3_stmt *statment;  
NSString *sql_selected = @"查询语句";  
result2 = sqlite3_prepare_v2(database, [sql_selected UTF8String], -1, &statment, nil); 
 if(result2 == SQLITE_OK){  
     //单步操作  
     while (sqlite3_step(statment) == SQLITE_ROW) {  
         int row = sqlite3_column_int(statment, 0);  
         char * rpwData = sqlite3_column_text(statment, 1);    
     }  
     sqlite3_finalize(statment);  
}   

//绑定变量,既就是插入操作的一种变种,比如我么那上面提到sqlite_exec可以执行插入操作,插入内容直接是写在sql字窜里,但是考虑到字窜涉及到无效的符号以及会一些严重的注入漏洞(比如以前听过的引号符号)。

NSString *sql_bind = @"insert into foo value(?,?)";  
result2 = sqlite3_prepare_v2(database, [sql_selected UTF8String], -1, &statment, nil); 
 if(result2 == SQLITE_OK){  
     sqlite3_bind_int(statment, 1, 235);  
     sqlite3_bind_text(statment, 2, "test", -1, nil);  
           sqlite3_finalize(statment);  
}  
if (sqlite3_step(statment) != SQLITE_DONE)  
     NSLog(@"error");  
sqlite3_finalize(statment);  
  
  
sqlite3_close(database);  

关于更多的,大伙可以自行百度,因为数据库的操作语法太怪异了,书上说是基本是基于c的,本人没学过c。看得有点心烦~

四、Core Data存储机制

大致浏览下基本感觉就是将对象归档搞成了可视化和简单化。 这块内容比较多。网上资料也挺丰富的。 暂时不做介绍了。

总结下:其实对于ios数据存储,最常用和主要要掌握的就是属性列表和数据库,因为两个是出镜率比较高的。 其他可能在数据存明显体现出储优势时,我们会去考虑用另外两种机制。 基础的来说,必须掌握属性列表和sqlite的操作存储。


相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程

 
分享到
 
 
     


android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   


Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合


领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...