iOS 数据保存几种方式总结

来源:互联网 发布:昌硕 软件测试工程师 编辑:程序博客网 时间:2024/06/04 22:00
[cpp] view plaincopyprint?
  1. 在iOS开发过程中,不管是做什么应用,都会碰到数据保存的问题。将数据保存到本地,能够让程序的运行更加流畅,不会出现让人厌恶的菊花形状,使得用户体验更好。下面介绍一下数据保存的方式:  
  2. 1.NSKeyedArchiver:采用归档的形式来保存数据,该数据对象需要遵守NSCoding协议,并且该对象对应的类必须提供encodeWithCoder:和initWithCoder:方法。前一个方法告诉系统怎么对对象进行编码,而后一个方法则是告诉系统怎么对对象进行解码。例如对Possession对象归档保存。  
  3. 定义Possession:  
[cpp] view plaincopyprint?
  1. @interface Possession:NSObject<NSCoding>{//遵守NSCoding协议  
  2.        NSString *name;//待归档类型  
  3. }  
  4. @implementation Possession  
  5. -(void)encodeWithCoder:(NSCoder *)aCoder{  
  6.             [aCoder encodeObject:name forKey:@"name"];  
  7. }  
  8. -(id)initWithCoder:(NSCoder *)aDecoder{  
  9.             name=[[aDeCoder decodeObjectforKey:@"name"] retain]; return self;  
[cpp] view plaincopyprint?
  1. }  
[cpp] view plaincopyprint?
  1. 归档操作:  
  2. 如果对Possession对象allPossession归档保存,只需要NSCoder子类NSKeyedArchiver的方法archiveRootObject:toFile: 即可。  
[cpp] view plaincopyprint?
  1. NSString *path = [self possessionArchivePath];  
  2. [NSKeyedArchiver archiveRootObject:allPossessions toFile: path ]  
[cpp] view plaincopyprint?
  1. 解压操作:  
  2.   
  3. 同样调用NSCoder子类NSKeyedArchiver的方法unarchiveRootObject:toFile: 即可    
  4. allPossessions = [[NSKeyedUnarchiver unarchiveObjectWithFile:path] retain];  
  5.   
  6. 缺点:归档的形式来保存数据,只能一次性归档保存以及一次性解压。所以只能针对小量数据,而且对数据操作比较笨拙,即如果想改动数据的某一小部分,还是需要解压整个数据或者归档整个数据。  
  7. 2.NSUserDefaults:用来保存应用程序设置和属性、用户保存的数据。用户再次打开程序或开机后这些数据仍然存在。NSUserDefaults可以存储的数据类型包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。如果要存储其他类型,则需要转换为前面的类型,才能用NSUserDefaults存储。具体实现为:  
  8. 保存数据:  
[cpp] view plaincopyprint?
  1. NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];  
  2. NSString *name =@”default string“;  
  3. [defaults setObject:firstName forKey:@"name"];  
  4.   //获得UIImage实例  
  5.   
  6. UIImage *image=[[UIImage alloc]initWithContentsOfFile:@"photo.jpg"];  
  7.   
  8. NSData *imageData = UIImageJPEGRepresentation(image, 100);//UIImage对象转换成NSData  
  9.   
  10. [defaults synchronize];//用synchronize方法把数据持久化到standardUserDefaults数据库  
[cpp] view plaincopyprint?
  1. 读取数据:  
  2.   
  3. NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];  
  4. NSString *name = [defaults objectForKey:@"name"];//根据键值取出name  
  5. NSData *imageData = [defaults dataForKey:@"image"];  
  6. UIImage *Image = [UIImage imageWithData:imageData];//NSData转换为UIImage  
[cpp] view plaincopyprint?
  1. 3. Write写入方式:永久保存在磁盘中。具体方法为:  
  2. 第一步:获得文件即将保存的路径:  
[cpp] view plaincopyprint?
  1. NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,  NSUserDomainMask,YES);  
[cpp] view plaincopyprint?
  1. //使用C函数NSSearchPathForDirectoriesInDomains来获得沙盒中目录的全路径。该函数有三个参数,目录类型、he domain mask、布尔值。其中布尔值表示是否需要通过~扩展路径。而且第一个参数是不变的,即为NSSearchPathDirectory 。在IOS中后两个参数也是不变的,即为:NSUserDomainMask 和 YES。  
  2. NSString *ourDocumentPath =[documentPaths objectAtIndex:0];  
  3.   
  4. 还有一种方法是使用NSHomeDirectory函数获得sandbox的路径。具体的用法为:  
  5.   
  6. NSString *sandboxPath = NSHomeDirectory();  
  7. // Once you have the full sandbox path, you can create a path from it,但是不能在sandbox的本文件层上写文件也不能创建目录,而应该是此基础上创建一个新的可写的目录,例如Documents,Library或者temp。  
  8. NSString *documentPath = [sandboxPath  
  9.             stringByAppendingPathComponent:@"Documents"];//将Documents添加到sandbox路径上,具体原因前面分析了!  
  10. 这两者的区别就是:使用NSSearchPathForDirectoriesInDomains比在NSHomeDirectory后面添加Document更加安全。因为该文件目录可能在未来发送的系统上发生改变。  
  11.   
  12. 第二步:生成在该路径下的文件:  
  13. NSString *FileName=[documentDirectory stringByAppendingPathComponent:fileName];//fileName就是保存文件的文件名  
  14. 第三步:往文件中写入数据:  
  15. [data writeToFile:FileName atomically:YES];//将NSData类型对象data写入文件,文件名为FileName  
  16.   
  17. 最后:从文件中读出数据:  
  18.   
  19. NSData data=[NSData dataWithContentsOfFile:FileName options:0 error:NULL];//从FileName中读取出数据  
  20. 4. SQLite:采用SQLite数据库来存储数据。SQLite作为一中小型数据库,应用ios中,跟前三种保存方式相比,相对比较复杂一些。还是一步步来吧!  
  21. 第一步:需要添加SQLite相关的库以及头文件:在项目文件的Build Phases下,找到Link Binary Library(ies),添加libsqlite3.0.dylib(libsqlite3.dylib与前者的区别暂时不知,两者应该差不多);在项目文件中头文件或者源文件中添加头文件#import "/usr/include/sqlite3.h"  
  22. 第二步:开始使用SQLite:  
[cpp] view plaincopyprint?
  1. NSArray *documentsPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask , YES);  
  2. NSString *databaseFilePath=[[documentsPaths objectAtIndex:0] stringByAppendingPathComponent:@"mydb"];  
  3. //上面两句已经比较熟悉了吧!   
  4. //打开数据库  
  5. if (sqlite3_open([databaseFilePath UTF8String], &database)==SQLITE_OK) {   
  6.         NSLog(@"sqlite dadabase is opened.");   
  7. }  
  8. elsereturn;}//打开不成功就返回  
  9. 在打开了数据库的前提下,如果数据库没有表,那就开始建表了哦!  
  10. char *error;   
  11. const char *createSql="create table(id integer primary key autoincrement, name text)";  
  12. if (sqlite3_exec(database, createSql, NULL, NULL, &error)==SQLITE_OK) {   
  13.         NSLog(@"create table is ok.");   
  14. }  
  15. else  
  16. {  
  17.        NSLog(@"error: %s",error);  
  18.        sqlite3_free(error);//每次使用完毕清空error字符串,提供给下一次使用  
  19. }   
[cpp] view plaincopyprint?
  1. 建表完成之后,就开始插入记录:  
  2.   
  3. const char *insertSql="insert into a person (name) values(‘gg’)";   
  4. if (sqlite3_exec(database, insertSql, NULL, NULL, &error)==SQLITE_OK) {   
  5.         NSLog(@"insert operation is ok.");   
  6. }  
  7.   
  8. else  
  9. {  
  10.        NSLog(@"error: %s",error);  
  11.        sqlite3_free(error);//每次使用完毕清空error字符串,提供给下一次使用  
  12. }   
  13. 下一步,查询记录:  
  14.   
  15. const char *selectSql="select id,name from a person";   
  16. sqlite3_stmt *statement;   
  17. if (sqlite3_prepare_v2(database,selectSql, -1, &statement, nil)==SQLITE_OK) {   
  18.         NSLog(@"select operation is ok.");   
  19. }  
  20. else  
  21. {  
  22.        NSLog(@"error: %s",error);  
  23.        sqlite3_free(error);  
  24. }   
  25. while(sqlite3_step(statement)==SQLITE_ROW) {   
  26. int _id=sqlite3_column_int(statement, 0);   
  27. NSString *name=(char*)sqlite3_column_text(statement, 1);   
  28. NSLog(@"row>>id %i, name %s",_id,name);   
  29. }  
  30. sqlite3_finalize(statement);  
  31.   
  32. 最后,关闭数据库:  
  33.   
  34. sqlite3_close(database);   
[cpp] view plaincopyprint?
  1. 注意:写入数据库,字符串可以采用char方式,而从数据库中取出char类型,当char类型有表示中文字符时,会出现乱码。这是因为数据库默认使用ascII编码方式。所以要想正确从数据库中取出中文,需要用NSString来接收从数据库取出的字符串。  
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机被标记骚扰电话怎么办 360摄像头不支持5g怎么办 摄像头不支持5g网络怎么办 家里的wifi卡了怎么办 办信用卡没有座机号码怎么办 拨打电话时显示号码有误怎么办 个体营业执照怎么办企业支付宝 没满16岁怎么办电话卡 我的电话卡丢了怎么办 公司注销地税没有补齐怎么办 公司没有固定电话怎么办信用卡 申请信用卡公司没有固定电话怎么办 办理信用卡公司没有固定电话怎么办 江门市固话欠费停机后怎么办 物业交钥匙地面有裂缝怎么办 深圳交通卡丢了怎么办 没装etc走etc怎么办 找不到过敏源身体痒怎么办 微信客服电话打不通怎么办 华为手机网络信号不好怎么办 酷我好友动态加载不了怎么办? 米兔电话手表停机了怎么办 糖猫电话手表停机了怎么办 360电话手表停机了怎么办 小天才电话手表停机怎么办 移动手机卡不知道号码怎么办 天猫退款手机号换了怎么办 科目二考试脚抖怎么办 面试新工作没打电话怎么办 怀孕5个月胎位低怎么办 做业务很害怕打电话怎么办 固定电话总是接到骚扰电话怎么办 电话卡通话被限制了怎么办? 手机名单拉黑了怎么办 被苹果6s被拉黑怎么办 重庆福利企业解聘残疾职工怎么办 被银行拉入黑名单怎么办 借的钱还不起了怎么办 支付宝手机号空号了怎么办 到处贷不到钱了怎么办 还不起钱借不到怎么办