IOS开发数据存储篇—IOS中的几种数据存储方式
IOS开发数据存储篇—IOS中的几种数据存储方式
发表于2016/4/5 21:02:09 421人阅读
分类: 数据存储
在项目开发当中,我们经常会对一些数据进行本地缓存处理。离线缓存的数据一般都保存在APP所在的沙盒之中。一般有以下几种:
1、PList(XML属性列表)
在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦
//写入文件
NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [doc stringByAppendingPathComponent:@"myself.plist"];
NSDictionary *dict = @{@"name": @"yixiang"};
[dict writeToFile:path atomically:YES];
//读取文件
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
2、偏好设置(NSUserDefaults)
将所有的东西都保存在同一个文件夹下面,且主要用于存储应用的设置信息)
//写入文件
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
[defaults setObject:@"yixiang" forKey:@"name"];
[defaults setInteger:27 forKey:@"age"];
[defaults synchronize];
//读取文件
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *name=[defaults objectForKey:@"name"];
NSInteger age=[defaults integerForKey:@"age"];
3、归档(NSCoding NSKeyedArchiver NSKeyedUnarchiver)
因为前两者都有一个致命的缺陷,只能存储常用的类型。归档可以实现把自定义的对象存放在文件中。
需要保存的对象必须遵守NSCoding协议,并且实现该协议中- (void)encodeWithCoder:(NSCoder )aCoder和 - (id)initWithCoder:(NSCoder )aDecoder方法。
YXPerson.h文件如下:
@interface YXPerson : NSObject<NSCoding>
@property(nonatomic,copy) NSString *name;
@property(nonatomic,assign) int age;
@end
YXPerson.m文件如下:
#import "YYPerson.h"
@implementation YYPerson
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInteger:self.age forKey:@"age"];
}
-(id)initWithCoder:(NSCoder *)aDecoder{
if (self=[super init]) {
self.name=[aDecoder decodeObjectForKey:@"name"];
self.age=[aDecoder decodeIntegerForKey:@"age"];
}
return self;
}
@end
在ViewController中对它进行写入和读取
//写入对象
YXPerson *p=[[YXPerson alloc]init];
p.name=@"yixiang";
p.age=27;
NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
NSString *path=[docPath stringByAppendingPathComponent:@"person.yixiang"];
[NSKeyedArchiver archiveRootObject:p toFile:path];
//读取对象
YXPerson *p=[NSKeyedUnarchiver unarchiveObjectWithFile:path];
4、SQLITE数据库
上述三种方法都无法存储大批量的数据,有性能的问题。
下面简单介绍一下,如何打开数据库,新增一张表格,然后对其进行增删改查的操作。
- (void)openDB{
//获取数据库文件路径
NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *fileName = [doc stringByAppendingPathComponent:@"students.sqlite"];
//将OC字符串转换为c语言的字符串
const char *cfileName = fileName.UTF8String;
//打开数据库文件(如果数据库文件不存在,那么该函数会自动创建数据库文件)
int result = sqlite3_open(cfileName, &_db);
if (result == SQLITE_OK) {//打开成功
NSLog(@"成功打开数据库");
}else{
NSLog(@"打开数据库失败");
}
}
- (void)createTable{
//创建表
const char *sql = "CREATE TABLE IF NOT EXISTS t_student(id integer PRIMARY KEY AUTOINCREMENT,name text NOT NULL,age integer NOT NULL);";
char *errmsg= NULL;
int result = sqlite3_exec(_db, sql, NULL, NULL, &errmsg);
if (result==SQLITE_OK) {
NSLog(@"创建表成功");
}else{
NSLog(@"创建表失败---%s",errmsg);
}
}
- (void)insertData{
//插入数据
for (int i=0; i<10; i++) {
//拼接sql语句
NSString *name = [NSString stringWithFormat:@"yixiangboy--%d",arc4random_uniform(100)];
int age = arc4random_uniform(20)+10;
NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_student (name,age) VALUES ('%@',%d);",name,age];
//执行SQL语句
char *errmsg = NULL;
sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &errmsg);
if (errmsg) {//如果有错误信息
NSLog(@"插入数据失败--%s",errmsg);
}else{
NSLog(@"插入数据成功");
}
}
}
- (void)deleteData{
//删除age小于15的数据
NSString *sql = [NSString stringWithFormat:@"DELETE FROM t_student WHERE age<15"];
char *errmsg = NULL;
sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &errmsg);
if (errmsg) {
NSLog(@"删除数据失败");
}else{
NSLog(@"删除数据成功");
}
}
- (void)updateData{
//大于20岁的都置为20岁
NSString *sql = [NSString stringWithFormat:@"UPDATE t_student set age=20 WHERE age>20"];
char *errmsg = NULL;
sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &errmsg);
if (errmsg) {
NSLog(@"更新数据失败");
}else{
NSLog(@"更新数据成功");
}
}
- (void)queryData{
const char *sql = "SELECT id,name,age FROM t_student WHERE age<20";
sqlite3_stmt *stmt = NULL;
//进行查询前的准备工作
if(sqlite3_prepare_v2(_db, sql, -1, &stmt, NULL)==SQLITE_OK){//SQL语句没有问题
NSLog(@"查询语句没有问题");
//每调用一次sqlite3_step函数,stmt就会指向下一条记录
while (sqlite3_step(stmt)==SQLITE_ROW) {//找到一条记录
//取出数据
//(1)取出第0个字段的值(int)
int ID=sqlite3_column_int(stmt, 0);
//(2)取出第一列字段的值(text)
const unsigned char *name = sqlite3_column_text(stmt, 1);
//(3)取出第二列字段的值(int)
int age = sqlite3_column_int(stmt, 2);
printf("%d %s %d\n",ID,name,age);
}
}else{
NSLog(@"查询语句有问题");
}
}
5、FMDB
FMDB是IOS中一个著名的SQLite数据库操作的开源项目。项目地址为:https://github.com/ccgus/fmdb
。是对SQLIite数据库的C语言接口进行了一层封装,使其满足面向对象的操作,接口比原生的SQLite接口简洁很多。同时也提供一些多线程,缓存,线程池的功能。以后的博客将进行详细介绍,这里不多说了。
6、CoreData
是苹果公司提供的数据持久化的一种方案。以后的博客将进行详细介绍,这里不多说了。
联系方式
微博:新浪微博
IOS开发数据存储篇—IOS中的几种数据存储方式的更多相关文章
- iOS开发——多线程OC篇&多线程中的单例
多线程中的单例 #import "DemoObj.h" @implementation DemoObj static DemoObj *instance; // 在iOS中,所有对 ...
- iOS开发中的4种数据持久化方式【二、数据库 SQLite3、Core Data 的运用】
在上文,我们介绍了ios开发中的其中2种数据持久化方式:属性列表.归档解档.本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运 ...
- iOS开发——实战OC篇&环境搭建之Xib(玩转UINavigationController与UITabBarController)
iOS开发——实战OC篇&环境搭建之Xib(玩转UINavigationController与UITabBarController) 前面我们介绍了StoryBoard这个新技术,和纯技术 ...
- iOS开发——实战OC篇&环境搭建之纯代码(玩转UINavigationController与UITabBarController)
iOS开发——实战OC篇&环境搭建之纯代码(玩转UINavigationController与UITabBarController) 这里我们就直接上实例: 一:新建一个项目singleV ...
- iOS开发OC基础:Xcode中常见英文总结,OC常见英文错误
在开发的过程中难免会遇到很多的错误,可是当看到系统给出的英文时,又不知道是什么意思.所以这篇文章总结了Xcode中常见的一些英文单词及词组,可以帮助初学的人快速了解给出的提示.多练习,就肯定能基本掌握 ...
- Delphi for iOS开发指南(8):在iOS应用程序中使用Tab组件来显示分页
Delphi for iOS开发指南(8):在iOS应用程序中使用Tab组件来显示分页 在FireMonkey iOS应用程序中的Tab Tab由FMX.TabControl.TTabControl定 ...
- Delphi for iOS开发指南(7):在iOS应用程序中使用WebBrowser组件
Delphi for iOS开发指南(7):在iOS应用程序中使用WebBrowser组件 在FireMonkey iOS应用程序中使用WebBrowser 在iOS平台上,FireMonkey使用T ...
- IOS开发使用委托delegate在不同窗口之间传递数据
IOS开发使用委托delegate在不同窗口之间传递数据是本文要介绍的内容,主要是来讲解如何使用委托delegate在不同窗口之间传递数据,具体内容来看详细内容.在IOS开发里两个UIView窗口之间 ...
- Delphi for iOS开发指南(6):在iOS应用程序中使用ComboBox组件来从列表中选择某一项
http://blog.csdn.net/delphiteacher/article/details/8924110 Delphi for iOS开发指南(6):在iOS应用程序中使用ComboBox ...
随机推荐
- Spring cloud ReadTimeout 问题解决
今天使用Spring cloud @FeignClient 调用远程服务的时候,出现readTimeout问题,通过找资料解决方式如下 在Spring.properties 配置文件中添加如下属性解决 ...
- Filter内容
1.利用Filter来过滤的时候大都是Http请求和Http响应,在doFilter()方法中,参数类是ServletRequest和ServletResponse ,使用的时候一般需要强制转换为H ...
- hdu 1712 (分组背包)
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17676 这个问题让我对分组背包更清晰了一点,主要是这个问题: 使用一维数组的 ...
- Object.defineProperty使用技巧
Object.definedProperty 该方法允许精确添加或修改对象的属性.通过赋值操作添加的普通属性是可枚举的,能够在属性枚举期间呈现出来(for...in 或 Object.keys 方法) ...
- csharp: Getting all image files in folder
/// <summary> /// /// </summary> /// <param name="sender"></param> ...
- JavaWeb中Servlet和JSP的分工案例
jsp和Servlet的分工: * JSP: > 作为请求发起页面,例如显示表单.超链接. > 作为请求结束页面,例如显示数据. * Servlet: &g ...
- JavaWeb请求-响应学习笔记
先来看一个流程图: 服务器处理请求的流程: (1)服务器每次收到请求时,都会为这个请求开辟一个新的线程. (2)服务器会把客户端的请求数据封装到request对象中,request就是请求数据的载 ...
- 【2014-08-23】Beyong Coding
be a product engineer,not be a engineer 选择比努力更重要 just code it,code it ,until you make it 缺的不是i ...
- 解决github访问过慢问题
解决github访问过慢问题 主要原因: DNS 自动解析较慢 http://github.global.ssl.fastly.net.ipaddress.com/#ipinfo 用文本编辑器打开ho ...
- anroid之异步不如异步
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) 使用自定义的CorePoolSize为7的Executor(Executors.newFixedTh ...