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

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

定义Possession:

@interface Possession:NSObject<NSCoding>{//遵守NSCoding协议

       NSString *name;//待归档类型

}

@implementation Possession

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

            [aCoder encodeObject:name forKey:@"name"];

}

-(void)initWithCoder:(NSCoder *)aDecoder{

            name=[[aDeCoder decodeObjectforKey:@"name"] retain];

}

归档操作:

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

NSString *path = [self possessionArchivePath];

[NSKeyedArchiver archiveRootObject:allPossessions toFile: path ]

解压操作:

同样调用NSCoder子类NSKeyedArchiver的方法unarchiveRootObject:toFile: 即可

allPossessions = [[NSKeyedUnarchiver unarchiveObjectWithFile:path] retain];

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

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

保存数据:

NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
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 =[NSUserDefaults standardUserDefaults];
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 full sandbox path, you can create a path from it,但是不能在sandbox的本文件层上写文件也不能创建目录,而应该是此基础上创建一个新的可写的目录,例如Documents,Library或者temp。
NSString *documentPath = [sandboxPath
            stringByAppendingPathComponent:@"Documents"];//将Documents添加到sandbox路径上,具体原因前面分析了!

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

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

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

第三步:往文件中写入数据:

[data writeToFile:FileName atomically:YES];//将NSData类型对象data写入文件,文件名为FileName

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

NSData data=[NSData dataWithContentsOfFile:FileName options:0 error:NULL];//从FileName中读取出数据
4. SQLite:采用SQLite数据库来存储数据。SQLite作为一中小型数据库,应用ios中,跟前三种保存方式相比,相对比较复杂一些。还是一步步来吧!

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

第二步:开始使用SQLite:

NSArray *documentsPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask , YES);
NSString *databaseFilePath=[[documentsPaths objectAtIndex:0] stringByAppendingPathComponent:@"mydb"];
//上面两句已经比较熟悉了吧! 
//打开数据库
if (sqlite3_open([databaseFilePath UTF8String], &database)==SQLITE_OK) { 
        NSLog(@"sqlite dadabase is opened."); 
}
else{ return;}//打开不成功就返回

在打开了数据库的前提下,如果数据库没有表,那就开始建表了哦!
char *error; 
const char *createSql="create table(id integer primary key autoincrement, name text)";
if (sqlite3_exec(database, createSql, NULL, NULL, &error)==SQLITE_OK) { 
        NSLog(@"create table is ok."); 
}
else
{
       NSLog(@"error: %s",error);
       sqlite3_free(error);//每次使用完毕清空error字符串,提供给下一次使用
}

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

const char *insertSql="insert into a person (name) values(‘gg’)"; 
if (sqlite3_exec(database, insertSql, NULL, NULL, &error)==SQLITE_OK) { 
        NSLog(@"insert operation is ok."); 
}

else
{
       NSLog(@"error: %s",error);
       sqlite3_free(error);//每次使用完毕清空error字符串,提供给下一次使用
}

下一步,查询记录:

const char *selectSql="select id,name from a person"; 
sqlite3_stmt *statement; 
if (sqlite3_prepare_v2(database,selectSql, -1, &statement, nil)==SQLITE_OK) { 
        NSLog(@"select operation is ok."); 
}
else
{
       NSLog(@"error: %s",error);
       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/tianyitianyi1/article/details/77131032

iOS 写入文件保存数据的方式的更多相关文章

  1. IOS四种保存数据的方式

    在iOS开发过程中,不管是做什么应用,都会碰到数据保存的问题.将数据保存到本地,能够让程序的运行更加流畅,不会出现让人厌恶的菊花形状,使得用户体验更好.下面介绍一下数据保存的方式: 1.NSKeyed ...

  2. IOS 四种保存数据的方式

    在iOS开发过程中,不管是做什么应用,都会碰到数据保存的问题.将数据保存到本地,能够让程序的运行更加流畅,不会出现让人厌恶的菊花形状,使得用户体验更好.下面介绍一下数据保存的方式: 1.NSKeyed ...

  3. hive分桶 与保存数据的方式

    创建分桶的表 create table t_buck(id int ,name string) clustered by (id ) sorted by (id) into 4 buckets  ; ...

  4. python3 购物车小程序,余额写入文件保存

    python3 购物车小程序,余额写入文件保存 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan goods = ( ...

  5. [ios]ios读写文件本地数据

    参考:http://blog.csdn.net/tianyitianyi1/article/details/7713103 ios - Write写入方式:永久保存在磁盘中.具体方法为:第一步:获得文 ...

  6. IOS的四种数据存储方式及优劣

    IOS有四种经常使用数据存储方式: 第一种方法:用NSUserDefaults存储配置信息 NSUserDefaults被设计用来存储设备和应用的配置信息.它通过一个工厂方法返回默认的.也是最经常使用 ...

  7. 怎样实现IOS开发中的数据存储方式

    iOS 开发中,一般有如下几种数据存储方式.需要根据具体的业务场景,选择 合适的数据存储方式. (1)  用户默认设置 – 这种情况通常不需要用户干预,如游戏通关信息,Video 播放记录,或者 Ap ...

  8. 八,ESP8266 文件保存数据

    应该是LUA介绍8266的最后一篇,,,,,,下回是直接用SDK,,然后再列个12345.......不过要等一两个星期,先忙完朋友的事情 前面几篇 用AT指令版本的 一,  http://www.c ...

  9. 八,ESP8266 文件保存数据(基于Lua脚本语言)

    https://www.cnblogs.com/yangfengwu/p/7533845.html 应该是LUA介绍8266的最后一篇,,,,,,下回是直接用SDK,,然后再列个12345...... ...

随机推荐

  1. poj3258

    题目翻译 二分法(其实两个单词的意思分别是河,跳格子游戏,至于为啥翻译成二分法- -只能说英语博大精深啊) 奶牛每年举办一场有特色的跳格子游戏(很明显题目翻译错误)涉及到在河里从一块岩石跳到另一块岩石 ...

  2. OpenRisc-43-or1200的IF模块分析

    引言 “喂饱饥饿的CPU”,是计算机体系结构设计者时刻要考虑的问题.要解决这个问题,方法大体可分为两部分,第一就是利用principle of locality而引进的cache技术,缩短取指时间,第 ...

  3. jQuery常用事件详解

    window.onload:在浏览器加载web页面时触发,可以写多次onload事件,但后者覆盖前者 ready:在浏览器加载web页面时触发,可以写多次ready事件,不会后者覆盖前者,依次从上向下 ...

  4. XML转义特殊字符

    正常来说,只有"<" 字符和"&"字符对于XML来说是严格禁止使用的. 需要注意的是: a. 转义序列各字符间不能有空格: b. 转义序列必须以& ...

  5. adb出现adb server is out of date时的解决的方法

    出错的原因是adb的port被其它程序的进程占据了,所以要做的就是找到并kill该进程.步骤:. 1.在cmd中运行adb nodaemon server,查看adb的port号是多少,普通情况下是5 ...

  6. android bitmap的 一些简单操作

    /** 获取 drawable 的图片 可以循环 1.图名 2.drawable 3.包名 **/ int imgid = getResources().getIdentifier("ic_ ...

  7. php session_set_save_handler 函数的用法(mysql)(转)

    <?php /*============================文件说明======================================== @filename:     s ...

  8. 解决java.sql.SQLException: Parameter number X is not an OUT parameter--转

    最近独自一个人写项目,孤军奋战的程序猿可真伤不起! Java 调用MYSQL带输入输出参数存储过程时如题错误:java.sql.SQLException: Parameter number X is ...

  9. iOS仿喜马拉雅FM做的毕业设计及总结(含新手福利源码)

    其实仿喜马拉雅FM很早就开始了,从我刚接触iOS开始,就开始仿做了一部分,眼尖的人都从我的github找到了那个项目.随着找到实习iOS工作,仿写就落下了,但唯一的收获就是给过去打了一个响亮的耳光,因 ...

  10. Android Studio下打jar包

    在我们使用Eclipse时,我们常常使用的第三方类库文件大多都是jar包形式,用起来很方便.但是jar包只能打包class文件,对于Android UI类库而言,我们常常需要打包资源文件,对于界面不多 ...