ios学习笔记-数据持久化
沙盒
沙盒是一种数据安全策略,只允许自己的应用访问目录。可以使用NSHomeDirectory()获取。
ios沙盒下有三个子目录:
1.Documents目录:用于存储比较大的文件活着需要频发女更新的数据,需要持久化的数据。获取代码:
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
2.Library目录: 该目录下有Preferences和Caches两个目录。前者用于存放应用程序的设置数据和状态信息,后者用于存储缓存文件。获取代码:
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
3.tmp目录:临时文件目录,随应用程序退出而清除,不能进行iTunes或iCloud备份。获取代码:
NSString *tempPath = NSTemporaryDirectory();
属性列表(plist文件)
属性列表是一种XML文件。NSArray和NSDictionary类提供了读写plist文件的方法。
- +arrayWithContentsOfFile:。NSArray类的类方法用于读取plist文件。
- +dictionaryWithContentsOfFile:。NSDictionary类的类方法用于读取plist文件。
- - initWithContentsOfFile:。NSArray和NSDictionary类都拥有此构造器方法,也能读取plist文件。
- - writeToFile:atomically:。用于写入plist文件。atomically参数为是否适用辅助文件,如果为true则先写入到辅助文件中,然后将辅助文件重命名为目标文件。如果为false,则直接写入目标文件。
示例代码(写入):
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *path = [documentPath stringByAppendingPathComponent:@"plist.plist"]; NSArray *array = @[@"a",@"b",@"c",@"d"]; NSString *plistPath = [self applicationDocumentsDirectoryFile]; [array writeToFile:plistPath atomically:YES];
示例代码(读取):
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *path = [documentPath stringByAppendingPathComponent:@"plist.plist"]; NSArray *array = [NSArray arrayWithContentsOfFile:path]; NSLog(@"%@",array);
对象归档
归档是一种序列化方式。需要归档对象的类必须实现NSCoding协议,而且每个成员变量应该是基本数据类型或实现NSCoding协议的某个类的实例。
写入:
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *path = [documentPath stringByAppendingPathComponent:@"plist.plist"]; NSDictionary *array = @{@"":@"a",@"":@"b"}; [NSKeyedArchiver archiveRootObject:array toFile:path];
读取:
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *path = [documentPath stringByAppendingPathComponent:@"plist.plist"]; NSDictionary *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; NSLog(@"%@",array);
SQLite数据库
SQLite可移植性强、小而容易使用。在运行时与实用他的程序共用相同的进程空间,不是单独的两个进程。在SQLite中,支持的常见数据类型有以下几种:
- INTEGER。整型
- REAL。浮点型
- TEXT。字符串类型,采用UTF-8,UTF-16字符编码
- BLOB。二进制,能存放任何二进制数据。
在SQLite中没有布尔类型,可采用整数0和1代替。也没有日期和时间类型,它们存储在TEXT、REAL、INTEGER类型中。
打开数据库:
/**
* 获取沙盒路径
*
* @return 沙盒路径
*/
- (NSString *)dataFilePath { NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *document = [path objectAtIndex:]; return [document stringByAppendingPathComponent:@"sqlite"]; } /**
* 打开数据库,如果没有则创建
*/
- (void)openSqlite {
sqlite3 *database;
//参数一:数据库文件路径(char类型) 参数二:数据库指针变量
if (sqlite3_open([[self dataFilePath] UTF8String], &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(NO, @"open database faid!");
NSLog(@"数据库创建失败");
}
else {
char *err;
//如果没有Note表则创建。PRIMARY KEY 主键
NSString *sql = @"CREATE TABLE IF NOT EXISTS Note (cdate TEXT PRIMARY KEY,content TEXT)";
//参数一:数据库指针变量 参数二:sql语句(char类型) 参数三:回调函数 参数四:回调函数所需参数
if (sqlite3_exec(database, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(NO, @"建表失败");
} //数据库打开失败,SQL语句执行失败,以及执行成功都需要关闭数据库,释放资源
sqlite3_close(database);
}
}
条件查询:
/**
* 根据条件查询一条
*
* @param text 主键
*
* @return 查询结果
*/
- (NSDictionary *)findById:(NSString *)text {
sqlite3 *database;
NSString *path = [self dataFilePath];
if (sqlite3_open([path UTF8String], &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(NO, @"数据库打开失败");
}
else {
NSString *sql = @"SELECT cdate,content FROM Note where cdate = ?"; NSLog(@"打开数据库"); //语句对象,SQL语句通过它执行
sqlite3_stmt *statement; /*
预处理过程
sqlite3_prepare_v2函数是SQL预处理语句。将SQL编译成二进制代码,提高执行速度 参数一:数据库指针变量 参数二:sql语句 参数三:全部SQL字符串长度。 如果nByte小于0,则函数取出zSql中从开始到第一个0终止符的内容;如果nByte不是负的,那么它就是这个函数能从zSql中读取的字节数的最大值。如果nBytes非负,zSql在第一次遇见’/000/或’u000’的时候终止 参数四:statement指针 参数五:SQL语句没有执行的部分语句。 上面提到zSql在遇见终止符或者是达到设定的nByte之后结束,假如zSql还有剩余的内容,那么这些剩余的内容被存放到pZTail中,不包括终止符
*/
int result = sqlite3_prepare_v2(database, [sql UTF8String], -, &statement, NULL);
NSLog(@"___________ %d",result);
if (result == SQLITE_OK) {
NSLog(@"预处理");
/*
sqlite3_bind_text:用于绑定SQL语句的参数
参数一:statement指针
参数二:参数序号(从1开始)
参数三:SQL语句参数(char类型)
参数四:字符串长度
参数五:函数指针,当数据库操作完成后会调用该函数
*/
sqlite3_bind_text(statement, , [text UTF8String], -, NULL); //执行。如果返回值为SQLITE_ROW说明数据没有遍历完
if (sqlite3_step(statement) == SQLITE_ROW) { /*
读取字符串类型的字段,第二个参数为select语句的索引(从0开始),下面就是读取cdata。
读取字段函数与字段类型对应,读取字段函数如下:
sqlite3_column_blob()
sqlite3_column_double()
sqlite3_column_int()
sqlite3_column_int64()
sqlite3_column_text()
sqlite3_column_text16()
*/
char *bufData = (char *)sqlite3_column_text(statement, ); NSString *strData = [[NSString alloc] initWithUTF8String:bufData]; //读取content
char *bufContent = (char *)sqlite3_column_text(statement, );
NSString *strContent = [[NSString alloc] initWithUTF8String:bufContent]; NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:strData,@"data",strContent,@"content", nil]; return dict;
}
} //释放statement
sqlite3_finalize(statement);
sqlite3_close(database);
}
return nil;
}
查询全部:
/**
* 查询全部数据
*
* @return 数组
*/
- (NSMutableArray *)findAll {
sqlite3 *database;
NSMutableArray *array = [[NSMutableArray alloc] init];
NSString *path = [self dataFilePath];
if (sqlite3_open([path UTF8String], &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(NO, @"数据库打开失败");
}
else {
NSString *sql = @"SELECT cdate,content FROM Note"; sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [sql UTF8String], -, &statement, NULL) == SQLITE_OK) { while (sqlite3_step(statement) == SQLITE_ROW) {
char *bufData = (char *)sqlite3_column_text(statement, );
NSString *strData = [[NSString alloc] initWithUTF8String:bufData]; NSLog(@"strData = %@",strData); char *bufContent = (char *)sqlite3_column_text(statement, );
NSString *strContent = [[NSString alloc] initWithUTF8String:bufContent]; NSLog(@"strContent = %@",strContent); NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:strData,@"data",strContent,@"content", nil];
[array addObject:dict];
} } sqlite3_finalize(statement);
sqlite3_close(database);
}
return array;
}
添加数据:
/**
* 添加数据
*
* @param model 所要插入的数据
*/
- (void)insert:(NSDictionary *)model {
sqlite3 *database;
NSString *path = [self dataFilePath];
if (sqlite3_open([path UTF8String], &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(NO, @"数据库打开失败");
}
else {
NSString *sql = @"INSERT OR REPLACE INTO Note(cdate,content) VALUES(?,?)"; sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [sql UTF8String], -, &statement, NULL) == SQLITE_OK) { char *bufData = (char *)[[model objectForKey:@"date"] UTF8String];
NSString *strContent = [model objectForKey:@"content"];
char *bufContent = (char *)[strContent UTF8String]; sqlite3_bind_text(statement, , bufData, -, NULL);
sqlite3_bind_text(statement, , bufContent, -, NULL); if (sqlite3_step(statement) != SQLITE_DONE) {
NSAssert(NO, @"插入数据失败");
}
else {
NSLog(@"插入成功");
} } sqlite3_finalize(statement);
sqlite3_close(database);
}
}
修改数据:
/**
* 添加数据
*
* @param model 所要插入的数据
*/
- (void)insert:(NSDictionary *)model {
sqlite3 *database;
NSString *path = [self dataFilePath];
if (sqlite3_open([path UTF8String], &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(NO, @"数据库打开失败");
}
else {
NSString *sql = @"INSERT OR REPLACE INTO Note(cdate,content) VALUES(?,?)"; sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [sql UTF8String], -, &statement, NULL) == SQLITE_OK) { char *bufData = (char *)[[model objectForKey:@"date"] UTF8String];
NSString *strContent = [model objectForKey:@"content"];
char *bufContent = (char *)[strContent UTF8String]; sqlite3_bind_text(statement, , bufData, -, NULL);
sqlite3_bind_text(statement, , bufContent, -, NULL); if (sqlite3_step(statement) != SQLITE_DONE) {
NSAssert(NO, @"插入数据失败");
}
else {
NSLog(@"插入成功");
} } sqlite3_finalize(statement);
sqlite3_close(database);
}
}
删除数据:
/**
* 删除数据
*
* @param cdata 所要删除数据的主键
*/
- (void)remove:(NSString *)cdata {
sqlite3 *database;
NSString *path = [self dataFilePath]; if (sqlite3_open([path UTF8String], &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(NO, @"数据库打开失败");
}
else {
NSString *sql = @"DELETE from Note where cdate =?"; sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [sql UTF8String], -, &statement, NULL) == SQLITE_OK) { sqlite3_bind_text(statement, , [cdata UTF8String], -, NULL); int result = sqlite3_step(statement); if (result != SQLITE_DONE) {
NSAssert(NO, @"删除数据失败");
}
else {
NSLog(@"删除数据成功");
} } sqlite3_finalize(statement);
sqlite3_close(database);
}
}
ios学习笔记-数据持久化的更多相关文章
- iOS学习之数据持久化详解
前言 持久存储是一种非易失性存储,在重启设备时也不会丢失数据.Cocoa框架提供了几种数据持久化机制: 1)属性列表: 2)对象归档: 3)iOS的嵌入式关系数据库SQLite3: 4)Core Da ...
- iOS学习笔记--数据存储
iOS应用数据存储的常用方式 XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档(NSCoding) SQLite3 Core Data 1. XM ...
- IOS学习:ios中的数据持久化初级(文件、xml、json、sqlite、CoreData)
IOS学习:ios中的数据持久化初级(文件.xml.json.sqlite.CoreData) 分类: ios开发学习2013-05-30 10:03 2316人阅读 评论(2) 收藏 举报 iOSX ...
- iOS学习笔记(十一)——JSON数据解析
在之前的<iOS学习——xml数据解析(九)>介绍了xml数据解析,这一篇简单介绍一下Json数据解析.JSON 即 JavaScript Object Natation,它是一种轻量级的 ...
- IOS学习笔记48--一些常见的IOS知识点+面试题
IOS学习笔记48--一些常见的IOS知识点+面试题 1.堆和栈什么区别? 答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来说,释放工作由程序员控制,容易产生memor ...
- iOS学习笔记-精华整理
iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...
- iOS学习笔记总结整理
来源:http://mobile.51cto.com/iphone-386851_all.htm 学习IOS开发这对于一个初学者来说,是一件非常挠头的事情.其实学习IOS开发无外乎平时的积累与总结.下 ...
- IOS学习笔记07---C语言函数-printf函数
IOS学习笔记07---C语言函数-printf函数 0 7.C语言5-printf函数 ------------------------- ----------------------------- ...
- iOS学习笔记之UITableViewController&UITableView
iOS学习笔记之UITableViewController&UITableView 写在前面 上个月末到现在一直都在忙实验室的事情,与导师讨论之后,发现目前在实验室完成的工作还不足以写成毕业论 ...
- IOS学习笔记02---语言发展概述,计算机语言简介.
IOS学习笔记02---语言发展概述,计算机语言简介. ------------------------------------------------------------------------ ...
随机推荐
- thinkPHP中省市级联下拉列表
公共函数放置位置common文件夹下common.php文件(此段代码也可放置在要使用的控制器中) 封装的下拉列表函数代码: /** * 根据列表拼装成一个下拉列表 ADD BY CK * @para ...
- 愉快的开始 - Windows程序设计(SDK)000
愉快的开始 让编程改变世界 Change the world by program 参考教材 购买链接:Windows程序设计(第5版)(珍藏版)(附CD-ROM光盘1张) 学习环境 视频演示:W ...
- Jasper_plug_install
1.open eclipse -> Help -> Eclipse Marketplace. 2.at new window, find jasper, will find Jaspers ...
- 在VS里面查看lua堆栈
extern std::string get_lua_stack(void); std::string stack = get_lua_stack(); std::string get_lua ...
- Effective Java实作hashCode() - 就是爱Java
hashCode()这个方法,也是定义在Object class中,这个是所有class的base class,因此所有的class也都继承这个方法,预设是传回这个对象储存的内存地址编号,因为Mix覆 ...
- GridView 设置背景透明以及Item的点击动画
//将点击时的背景色设置为透明 gridView.setSelector(new ColorDrawable(Color.TRANSPARENT)); 此时点击GridView的每个Item就不会出现 ...
- VS2010的openssl源码编译方法
http://download.csdn.net/download/soucula/9591308
- adb链接手机调试android应用
adb链接手机调试android应用 hulk@hulk-Lenovo:~$ adb devices List of devices attached ???????????? no permiss ...
- c++ 02
一.堆内存的动态分配与释放 malloc/calloc/realloc/free new/delete:详见memory.cpp 1.通过new运算符分配单个变量 数据类型* 指针变量 = new 数 ...
- python3-day2(基本回顾)
1.作用域 1>外层变量可以被内层变更使用 2>内层变更不可以被外层使用 global nonlocal 2.对于Python,一切事物都是对象,对象基于类创建 3.练习 有如下值集合 [ ...