当前位置:首页 > 操作系统 > Ios

iOS 常用四种数据存储方式

iOS 常用四种数据存储方式

 

   iOS 开发过程中 , 不管是做什么应用 , 都会碰到数据保存的问题。将数据保存到本地 , 能够让程序的运行更加流畅 , , 使得用户体验更好。下面介绍 ? 一下数据保存的方式 :

1.NSKeyedArchiver: 采用归档的形式来保存数据 , 该数据对象需要遵守 NSCoding 协议 , 并且该对象对应的类必须提 encodeWithCoder: initWithCoder: 方法。前 ? 一个方法告诉系统怎么对对象进行编码 , 而后 ? 一个方法则是告诉系统怎么对对象进行解码。 例如对 Possession 对象归档保存。

定义 Possession:
@interfacePossession:NSObject{           // 遵守 NSCoding 协议

      NSString *name;                                // 待归档类型

}

@implementation Possession

  -(void)encodeWithCoder:(NSCoder *)aCoder{ 

[aCoderencodeObject:nameforKey:@"name"]; }

 

-(void)initWithCoder:(NSCoder *)aDecoder{
name=[[aDeCoder decodeObjectforKey:@"name"] retain];

}

归档操作 : 如果对 Possession 对象 allPossession 归档保存 , 只需要 NSCoder 子类 NSKeyedArchiver 的方法 archiveRootObject:toFile: 即可。

NSString *path =[selfpossessionArchivePath];
[NSKeyedArchiver archiveRootObject:allPossessions toFile: path ]

解压操作 : 同样调用 NSCoder 子类 NSKeyedArchiver 的方法 unarchiveRootObject:toFile: 即可 allPossessions =[[NSKeyedUnarchiverunarchiveObjectWithFile:path] retain];

缺点 : 归档的形式来保存数据 , 只能 ? 一次性归档保存以及 ? 一次性解压。所以只能针对小量数据 , 而且对数据操作比较笨拙 , 即如果想改动数据的某 ? 一小部分 , 还是需要解压整个数据或者归档整个数据。

 

 2.NSUserDefaults:用来保存应用程序设置和属性、用户保存的数据。用户再次打开程序或开机后这些数据仍然存在。NSUserDefaults可以存储的数据类型包括:NSDataNSStringNSNumberNSDateNSArray NSDictionary。如果要存储其他类型,则需要转换为前面的类型,才能用NSUserDefaults存储。具体实现为:

保存数据 :

NSUserDefaults *defaults=[NSUserDefaultsstandardUserDefaults];

NSString *name =@”default string“;
[defaults setObject:firstName forKey:@"name"];

// 获得 UIImage 实例
UIImage *image=[[UIImage alloc]initWithContentsOfFile:@"photo.jpg"];
NSData *imageData = UIImageJPEGRepresentation(image, 100);//UIImage
对象转换成 NSData [defaults synchronize];// synchronize 方法把数据持久化到 standardUserDefaults 数据库

读取数据 :

NSUserDefaults *defaults=[NSUserDefaultsstandardUserDefaults];
NSString *name = [defaults objectForKey:@"name"];//
根据键值取出 name
NSData *imageData = [defaults dataForKey:@"image"];
UIImage *Image = [UIImage imageWithData:imageData];//NSData
转换为 UIImage

 

3. Write 写入方式 : 永久保存在磁盘中。具体方法为 :
? 一步 : 获得文件即将保存的路径 :
NSArray*documentPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES); // 使用 C 函数 NSSearchPathForDirectoriesInDomains 来获得沙盒中目录的全路径。该函数有三个参数 , 目录类型、 he domain mask 、布尔值。其中布尔值表示是否需要通过 ? ~扩展路径。 而且第 ? 一个参数是不变的 , 即为 NSSearchPathDirectory 。在 IOS 中后两个参数也是不变的 , 即为 :NSUserDomainMask YES


NSString *ourDocumentPath =[documentPaths objectAtIndex:0];

还有 ? 一种方法是使用 NSHomeDirectory 函数获得 sandbox 的路径。具体的用法为 :

NSString *sandboxPath = NSHomeDirectory();
// Once you have the fullsandbox path, you can create a path from it, 但是不能在 sandbox 的本文件层上写 文件也不能创建目录 , 而应该是此基础上创建 ? 一个新的可写的目录 , 例如 Documents,Library 或者 temp NSString *documentPath = [sandboxPath

stringByAppendingPathComponent:@"Documents"];// Documents 添加到 sandbox 路径上 , 具体原 因前面分析了 !

这两者的区别就是 : 使用 NSSearchPathForDirectoriesInDomains 比在 NSHomeDirectory 后面添加 Document 更加安全。因为该文件目 录可能在未来发送的系统上发生改变。

第二步 : 生成在该路径下的文件 :  

NSString *FileName=[documentDirectorystringByAppendingPathComponent:fileName];//fileName 就是保存文件的文件

第三步 : 往文件中写入数据 :
[datawriteToFile:FileNameatomically:YES];// NSData 类型对象 data 写入文件 , 文件名为 FileName

最后 : 从文件中读出数据 :  

NSDatadata=[NSDatadataWithContentsOfFile:FileName options:0 error:NULL];// FileName 中读取出数据

 

4. SQLite: 采用 SQLite 数据库来存储数据。 SQLite 作为 ? 一中小型数据库 , 应用 ios , 跟前三种保存方式相比 , 相对 比较复杂 ? 一些。还是 ? 一步步来吧 ! 或者用第三方的 FMDB 数据库来实现,详细 FMDB 的用法转到 http://blog.csdn.net/eduora_meimei/article/details/44061771

 

? 一步 : 需要添加 SQLite 相关的库以及头文件 : 在项目文件的 BuildPhases , 找到 Link Binary Library(ies), 添加 libsqlite3.0.dylib(libsqlite3.dylib 与前者的区别暂时不知 , 两者应该差不多 ); 在项目文件中头文件或者源文件中添加头文件 #import"/usr/include/sqlite3.h"
第二步 : 开始使用 SQLite:

使用前注意 : 如果不往数据库里面添加任何的表 , 这个数据库等于没有建立 , 不会在硬盘上产生任何文件 , 如果数据库已经存在 , 则会打开这个数据库。

NSArray*documentsPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *databaseFilePath=[[documentsPathsobjectAtIndex:0]stringByAppendingPathComponent:@"mydb"];

// 上面两句已经比较熟悉了吧 !
//
打开数据库
if (sqlite3_open([databaseFilePath UTF8String], &database)==SQLITE_OK) {

NSLog(@"sqlite dadabaseisopened."); }

else{ return;}// 打开不成功就返回

在打开了数据库的前提下 , 如果数据库没有表 , 那就开始建表了哦 !  

char *error;
const char *createSql="create table(id integer primary keyautoincrement,name text)"; if (sqlite3_exec(database, createSql, NULL,NULL,&error)==SQLITE_OK) {

NSLog(@"create table is ok."); }

else {

sqlite3_free(error);// 每次使用完毕清空 error 字符串 , 提供给下 ? 一次使用 }

建表完成之后 , 就开始插入记录 :  

const char *insertSql="insert intoaperson (name) values(‘gg’)";
if (sqlite3_exec(database, insertSql, NULL, NULL, &error)==SQLITE_OK) {

NSLog(@"insert operation isok.");}

else {

NSLog(@"error: %s",error);

NSLog(@"error: %s",error);

sqlite3_free(error);// 每次使用完毕清空 error 字符串 , 提供给下 ? 一次使用 }

? 一步 , 查询记录 :

const char *selectSql="selectid,namefrom a person";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database,selectSql, -1, &statement,nil)==SQLITE_OK){

NSLog(@"select operation isok.");}

else {

sqlite3_free(error); }

while(sqlite3_step(statement)==SQLITE_ROW){
int _id=sqlite3_column_int(statement, 0);
NSString *name=(char*)sqlite3_column_text(statement,1);NSLog(@"row>>id %i, name %s",_id,name);
}
sqlite3_finalize(statement);
最后 , 关闭数据库 :
sqlite3_close(database);

注意 : 写入数据库 , 字符串可以采用 char 方式 , 而从数据库中取出 char 类型 , char 类型有表示中文字符时 , 会出现乱码。这是因为数据库默认使用 ascII 编码方式。所以要想正确从数据库中取出中文 , 需要用 NSString 来接收从数据库取出的字符串。  

 

 

原文:http://blog.csdn.net/eduora_meimei/article/details/44198579


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!