本地持久化存储

一、沙盒机制

沙盒是什么

每个iOS应用都有属于自己的应用沙盒(沙盒就是文件系统目录),与其他文件系统隔离,每个应用都只能访问自己的沙盒。

沙盒的路径结构

  • Document:适合存储重要的数据, iTunes同步应用时会同步该文件下的内容,(比如游戏中的存档)
 NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
  • Library/Caches:适合存储体积大,不需要备份的非重要数据,iTunes不会同步该文件
NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
  • Library/Preferences: 通常保存应用的设置信息, iTunes同步该应用时会同步此文件夹中的内容
  • tmp:保存应用的临时文件,用完就删除,系统可能在应用没在运行时删除该目录下的文件,iTunes不会同步该文件
NSString *path = NSTemporaryDirectory();

获取沙盒路径

通过NSSearchPathForDirectoriesInDomains 方法来获取沙盒路径

二、数据存储常用方式

偏好设置(NSUserDefaults)

  • 偏好设置是专门保存应用的配置信息的,如用户名、密码等,一般不要在偏好设置中保存其他数据。
  • NSUserDefaults保存的数据都是不可变的,取出来的数据也是不可变类型,通过键值对方式进行存取。
  • 如果没有调用synchronize方法,系统会根据I/O情况不定时刻地保存到文件中。所以如果需要立即写入文件的就必须调用synchronize方法。
  • 偏好设置会将所有数据保存到同一个文件中。即preference目录下的一个以此应用包名来命名的plist文件。

实例如下:

//获得NSUserDefaults文件
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//保存内容
[userDefaults setValue:@"sunsan" forKey:username];
[userDefaults setValue:@"abcd1234" forKey:userpassword];
//读取内容
NSString * name = [userDefaults valueForKey:username];
NSString * password = [userDefaults valueForKey:userpassword];

plist存储

plist文件是将某些特定的类,通过XML文件的方式保存在目录中。
可以被序列化的类型有以下几种:

NSArray;
NSMutableArray;
NSDictionary;
NSMutableDictionary;
NSData;
NSMutableData;
NSString;
NSMutableString;
NSNumber;
NSDate;

实例如下:

//设置文件名
NSString *fileName = [path stringByAppendingPathComponent:@"students.plist"];
//写入文件
[array writeToFile:fileName atomically:YES];
//读取
NSArray *result = [NSArray arrayWithContentsOfFile:fileName];

归档解归档

通过使用NSKeyArchiverarchiveRootObject: toFile:方法直接归档一个对象,使用NSKeyedUnarchiverunarchiveObjectWithFile:解档对象。
在归档自定义对象的时候,必须遵守NSCoding协议,并实现协议方法:

  • 每次归档对象时,都会调用encodeWithCoder:,一般在这个方法里面指定如何归档对象中的每个实例变量;
  • 每次从文件中恢复对象时,都会调用initWithCoder:,一般在这个方法里面指定如何解码文件中的数据为对象的实例变量。

实例如下:

//设置文件名
NSString *fileName = [path stringByAppendingPathComponent:@"person.archiver"];
//进行归档
[NSKeyedArchiver archiveRootObject:per toFile:fileName];
//进行解归档
Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:fileName];

以上的存储方法,都是覆盖存储。如果想要增加一条数据就必须把整个文件读出来,然后修改数据后再把整个内容覆盖写入文件,并不适合大量数据的存取。


SQLite

SQLite简介

SQLite是一个轻量级关系数据库,最初的设计目标是用于嵌入式系统,它占用资源非常少。在iOS中,只要导入libsqlite3.0.tbd依赖以及引入sqlite3.h头文件即可。
SQLite是无类型的数据库,可以保存任何类型的数据,对于SQLite来说对字段不指定类型是完全有效的

SQLite近似类似规则

  • 如果类型字符串中包含“int”,那么该字段的亲缘关系是INTEGER
  • 如果类型字符串中包含“char”,“clob”或“text”,那么该字段的亲缘类型是TEXT
  • 如果类型字符串中包含“blob”,那么该字段的亲缘类型是NONE
  • 如果类型字符串中包含“real”,“floa”或“doub”,那么该字段的亲缘类型是REAL
  • 其余情况下,字段的亲缘类型为NUMERIC

SQLite字段的约束条件

  • not null —— 非空
  • unique —— 唯一
  • primary key —— 主键
  • foreign key —— 外键
  • check —— 条件检查,确保一列中所有的值满足一定条件
  • default —— 默认
  • autoincrement —— 自增型变量,该字段数据如果为整形可以自动加1

SQLite语句

SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL。

  • DML主要包含数据的增删改:
    数据插入(insert):insert into 表名(字段1,字段2,……)values(字段1值,字段2值,……)
    数据更新(update):update 表名 set 字段1=修改值1,字段2=修改值2,……where 条件
    数据删除(delete):delete from 表名 where 条件
  • DQL主要用于查询获得表中的数据,其中差用的关键字包含where,order by,group by和having
    数据查询(select):select 查找字段 from 表名 where 条件
  • DDL部分包含创建或者删除表格,定义索引,规定表之间的链接,以及施加表间的约束
    建表命令:create table if not exists 表名(字段1 约束1 约束2……,字段2 约束1 约束2)
    删表命令:drop table if exists 表名

FMDB

FMDB是一款轻量级的框架,以OC的方式对SQLite的C语言API进行封装,对多线程并发进行处理,所以线程安全。

FMDB常用类

FMDatabase:一个FMDatabase对象就代表一个单独的SQLite数据库,用来执行SQL语句
FMResultSet:使用FMDatabase执行查询后的结果集
FMDatabaseQueue:用于在多线程中执行多个查询或更新,它是线程安全的

FMDB操作

  • 使用FMDataBase类建立数据库
//获取Documents路径
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject ;
//生成数据库路径
NSString *filePath = [path stringByAppendingPathComponent:@"person.sqlite"];
//获取数据库
database = [FMDatabase databaseWithPath:filePath];
if ([database open]) {
    NSLog(@"数据库打开成功");
}else{
    NSLog(@"打开数据库失败");
}
  • 表的创建
BOOL result = [database executeUpdate:@"create table if not exists person (name text primary key not null, city text, age integer)"];
if (result) {
    NSLog(@"创建表成功");
} else {
    NSLog(@"创建表失败");
}
  • 添加数据
BOOL result = [database executeUpdate:@"insert into person (name,city,age) values (?,?,?)",per.name,per.city,@(per.age)];
if (result) {
    NSLog(@"添加数据成功");
} else {
    NSLog(@"添加数据失败");
}
  • 删除数据
BOOL result = [database executeUpdate:@"delete from person where name = ?",per.name];
if (result) {
    NSLog(@"删除数据成功");
} else {
    NSLog(@"删除数据失败");
}
  • 修改数据
BOOL result = [database executeUpdate:@"update person set city = ?,age = ? where name = ?",per.city,@(per.age),per.name];
if (result) {
    NSLog(@"修改数据成功");
} else {
    NSLog(@"修改数据失败");
}
  • 查询所有数据
FMResultSet *result = [database executeQuery:@"select * from person"];
while ([result next]) {
    Person *per = [[Person alloc] init];
    per.name = [result stringForColumn:@"name"];
    per.city = [result stringForColumn:@"city"];
    per.age =  [result intForColumn:@"age"];
     [array addObject:per];
}
  • 关闭数据库
if ([database close]) {
    NSLog(@"关闭数据库成功");
} else {
    NSLog(@"关闭数据库失败");
}

参考:完整项目资料下载

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容