服务器之家

服务器之家 > 正文

IOS 数据存储详解及实例代码

时间:2021-03-04 13:59     来源/作者:zhangke3016

ios应用数据存储的常用方式

  1. xml属性列表(plist)归档
  2. preference(偏好设置)
  3. nskeyedarchiver归档(nscoding)
  4. sqlite3
  5. core data

1. xml属性列表(plist)归档

每个ios应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离。应用必须待在自己的沙盒里,其他应用不能访问该沙盒。

IOS 数据存储详解及实例代码

应用沙盒结构分析:

应用程序包:包含了所有的资源文件和可执行文件

documents:保存应用运行时生成的需要持久化的数据,itunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录

tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。itunes同步设备时不会备份该目录

library/caches:保存应用运行时生成的需要持久化的数据,itunes同步设备时不会备份该目录。一般存储体积大、不需要备份的非重要数据

library/preference:保存应用的所有偏好设置,ios的settings(设置)应用会在该目录中查找应用的设置信息。itunes同步设备时会备份该目录

应用沙盒目录的常见获取方式

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
沙盒根目录:nsstring *home = nshomedirectory();
documents:(2种方式)
1. 利用沙盒根目录拼接”documents”字符串
//不建议采用,因为新版本的操作系统可能会修改目录名
nsstring *home = nshomedirectory();
nsstring *documents = [home stringbyappendingpathcomponent:@"documents"];
2. 利用nssearchpathfordirectoriesindomains函数
// nsuserdomainmask 代表从用户文件夹下找
// yes 代表展开路径中的波浪字符“~”
nsarray *array = nssearchpathfordirectoriesindomains(nsdocumentdirectory, nsuserdomainmask, no);
// 在ios中,只有一个目录跟传入的参数匹配,所以这个集合里面只有一个元素
nsstring *documents = [array objectatindex:0];
tmp:
nsstring *tmp = nstemporarydirectory();
library/caches:
跟documents类似的2种方法:
1. 利用沙盒根目录拼接”caches”字符串
2. 利用nssearchpathfordirectoriesindomains函数(将函数的第2个参数改为:nscachesdirectory即可)
library/preference:
通过nsuserdefaults类存取该目录下的设置信息

属性列表

属性列表是一种xml格式的文件,拓展名为plist

如果对象是nsstring、nsdictionary、nsarray、nsdata、nsnumber等类型,就可以使用writetofile:atomically:方法直接将对象写到属性列表文件中

如:将一个nsdictionary对象归档到一个plist属性列表中

?
1
2
3
4
5
6
7
8
9
10
11
/ /获取路径
nsstring *path = nssearchpathfordirectoriesindomains(nsdocumentdirectory, nsuserdomainmask, yes)[0];
path = [path stringbyappendingpathcomponent:@"save.plist"];
/ /将数据封装成字典
//不能存储对象
nsmutabledictionary *dict = [nsmutabledictionary dictionary];
[dict setobject:@"小黄" forkey:@"name"];
[dict setobject:@"12345678" forkey:@"phone"];
[dict setobject:@"24" forkey:@"age"];
// 将字典持久化到documents/save.plist文件中
[dict writetofile:path atomically:yes];

IOS 数据存储详解及实例代码

恢复nsdictionary

?
1
2
3
4
5
6
读取属性列表,恢复nsdictionary对象
// 读取documents/save.plist的内容,实例化nsdictionary
nsdictionary *dict = [nsdictionary dictionarywithcontentsoffile:path];
nslog(@"name:%@", [dict objectforkey:@"name"]);
nslog(@"phone:%@", [dict objectforkey:@"phone"]);
nslog(@"age:%@", [dict objectforkey:@"age"]);

**nsdictionary—(writetofile:atomically:)—-> save.plist
(属性列表文件)**

save.plist(属性列表文件)—(dictionarywithcontentsoffile:)—> nsdictionary

2. preference(偏好设置)

很多ios应用都支持偏好设置,比如保存用户名、密码、字体大小等设置,ios提供了一套标准的解决方案来为应用加入偏好设置功能
每个应用都有个nsuserdefaults实例,通过它来存取偏好设置

?
1
2
3
4
5
//比如,保存用户名、字体大小、是否自动登录
nsuserdefaults *defaults = [nsuserdefaults standarduserdefaults];
[defaults setobject:@"mr.zk" forkey:@"username"];
[defaults setfloat:18.0f forkey:@"text_size"];
[defaults setbool:yes forkey:@"auto_login"];

IOS 数据存储详解及实例代码

?
1
2
3
4
5
//读取上次保存的设置
nsuserdefaults *defaults = [nsuserdefaults standarduserdefaults];
nsstring *username = [defaults stringforkey:@"username"];
float textsize = [defaults floatforkey:@"text_size"];
bool autologin = [defaults boolforkey:@"auto_login"];

注意:userdefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。出现以上问题,可以通过调用synchornize方法强制写入
[defaults synchornize];

3. nskeyedarchiver归档(nscoding)

nskeyedarchiver

如果对象是nsstring、nsdictionary、nsarray、nsdata、nsnumber等类型,可以直接用nskeyedarchiver进行归档和恢复

不是所有的对象都可以直接用这种方法进行归档,只有遵守了nscoding协议的对象才可以

* nscoding协议有2个方法:*

encodewithcoder:

每次归档对象时,都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量,可以使用encodeobject:forkey:方法归档实例变量

initwithcoder:

每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeobject:forkey方法解码实例变量

归档一个nsarray对象到documents/array.data

?
1
2
3
4
nsstring *path = nssearchpathfordirectoriesindomains(nscachesdirectory, nsuserdomainmask, yes)[0];
path = [path stringbyappendingpathcomponent:@"array.data"];
nsarray *array = [nsarray arraywithobjects:@”a”,@”b”,nil];
[nskeyedarchiver archiverootobject:array tofile:path];

IOS 数据存储详解及实例代码

恢复(解码)nsarray对象

?
1
nsarray *array = [nskeyedunarchiver unarchiveobjectwithfile:path];

nsarray—(archiverootobject:tofile:)—-> array.data

array.data—(unarchiveobjectwithfile:)—> nsarray

?
1
2
3
4
5
6
nskeyedarchiver-归档person对象(person.h)
@interface person : nsobject<nscoding>
@property (nonatomic, strong) nsstring *name;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) float height;
@end
?
1
2
3
4
5
6
7
8
9
10
11
12
13
@implementation person
- (void)encodewithcoder:(nscoder *)encoder {
  [encoder encodeobject:self.name forkey:@"name"];
  [encoder encodeint:self.age forkey:@"age"];
  [encoder encodefloat:self.height forkey:@"height"];
}
- (id)initwithcoder:(nscoder *)decoder {
  self.name = [decoder decodeobjectforkey:@"name"];
  self.age = [decoder decodeintforkey:@"age"];
  self.height = [decoder decodefloatforkey:@"height"];
  return self;
}
@end
?
1
2
3
4
5
6
7
8
//归档(编码)
person *person = [[[person alloc] init] autorelease];
person.name = @"zk";
person.age = 24;
person.height = 1.73f;
[nskeyedarchiver archiverootobject:person tofile:path];
//恢复(解码)
person *person = [nskeyedunarchiver unarchiveobjectwithfile:path];

如果父类也遵守了nscoding协议,请注意:
应该在encodewithcoder:方法中加上
[super encodewithcode:encode];
确保继承的实例变量也能被编码,
即也能被归档应该在initwithcoder:方法中加上
self = [super initwithcoder:decoder];
确保继承的实例变量也能被解码,即也能被恢复

nsdata

使用archiverootobject:tofile:方法可以将一个对象直接写入到一个文件中,但有时候可能想将多个对象写入到同一个文件中,那么就要使用nsdata来进行归档对象

nsdata可以为一些数据提供临时存储空间,以便随后写入文件,或者存放从磁盘读取的文件内容。可以使用[nsmutabledata data]创建可变数据空间

IOS 数据存储详解及实例代码

?
1
2
3
4
5
6
7
8
9
10
11
12
//归档(编码)
// 新建一块可变数据区
nsmutabledata *data = [nsmutabledata data];
// 将数据区连接到一个nskeyedarchiver对象
nskeyedarchiver *archiver = [[[nskeyedarchiver alloc] initforwritingwithmutabledata:data] autorelease];
// 开始存档对象,存档的数据都会存储到nsmutabledata中
[archiver encodeobject:person1 forkey:@"person1"];
[archiver encodeobject:person2 forkey:@"person2"];
// 存档完毕(一定要调用这个方法)
[archiver finishencoding];
// 将存档的数据写入文件
[data writetofile:path atomically:yes];

利用归档实现深复制

?
1
2
3
4
5
6
7
8
9
//恢复(解码)
// 从文件中读取数据
nsdata *data = [nsdata datawithcontentsoffile:path];
// 根据数据,解析成一个nskeyedunarchiver对象
nskeyedunarchiver *unarchiver = [[nskeyedunarchiver alloc] initforreadingwithdata:data];
person *person1 = [unarchiver decodeobjectforkey:@"person1"];
person *person2 = [unarchiver decodeobjectforkey:@"person2"];
// 恢复完毕
[unarchiver finishdecoding];

person1—(archiveddatawithrootobject:)—>nsdata—(unarchiveobjectwithdata:)—>person2

4. sqlite3(之后补充)

5. core data(之后补充)

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

原文链接:http://blog.csdn.net/zhangke3016/article/details/53574894

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-07-29
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
返回顶部