欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-02-15 20:09:22
ios应用数据存储的常用方式 xml属性列表(plist)归档 preference(偏好设置) nskeyedarchiver归档(nscoding...

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同步设备时会备份该目录

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

沙盒根目录: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属性列表中

/ /获取路径
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

读取属性列表,恢复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实例,通过它来存取偏好设置

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

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

//读取上次保存的设置
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

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对象

nsarray *array = [nskeyedunarchiver unarchiveobjectwithfile:path];

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

array.data—(unarchiveobjectwithfile:)—> nsarray

nskeyedarchiver-归档person对象(person.h)
@interface person : nsobject<nscoding>
@property (nonatomic, strong) nsstring *name;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) float height;
@end
@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
//归档(编码)
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 数据存储详解及实例代码

//归档(编码)
// 新建一块可变数据区
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];

利用归档实现深复制

//恢复(解码)
// 从文件中读取数据
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(之后补充)

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