iOS设计中 UI设计之沙盒与数据持久化

  沙盒机制

·沙盒是一种安全体系,每一个ios应用程序都会为自己创建一个文件系统目录(文件夹),这个独立,封闭,安全的空间叫做沙盒;

1.独立:每个应用程序有一个自己的沙盒,两个应用程序不能共用一个沙盒,

2.封闭:每个应用程序的沙盒只有它自己才能使用 两个沙盒之间基本不通信

3.安全:有不同的文件夹,彼此间的文件保存时间不同

沙盒这个文件夹下默认有三个文件夹; 

1.document:用于存储持久化文件,iTunes会自动备份该文件夹。注意,不要放音频 视频等过大文件 2.library:下有caches和preferences caches:用于存放体积较大也不是很很重要的数据资源。iTunes不会对其进行备份,该文件夹内资源不会在程序退出时就清楚 preferences:顾名思义,保存应用的所有偏好设置,iTunes会自动将其备份,ios的setting应用汇在该目录下查找应用的设置信息。注意:不要直接操作该文件夹,要通过NSUserDefaults类来访问,设置

3.tmp:保存应用程序时所需的临时文件。iTunes不会对其进行备份,应用没有运行时可能会清除该文件夹下的文件,iPhone重启时也会删除该文件夹下的文件

关于获取沙盒下5个目录的路径方法,有2种

  1. 第一种 // 第一步:获取沙盒主路径的地址 NSString homePathStr = NSHomeDirectory(); // 第二步:在沙盒主路径后拼接Documents,拼接出来documents文件夹的路径 NSString documentPathStr = [homePathStr stringByAppendingPathComponent:@"Library/Caches"]; 

2.第二种
NSString *documentPathStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; // NSDocumentDirectory 表示要获取Document文件夹的地址 // NSUserDomainMask 表示用户的主目录 // 第三个参数表示 展开“~”的地址,设置为YES 为完整的路径。 // NSSearchPathForDirectoriesInDomains获取的是一个数组,数组只有一个元素,所以可以直接获取objectAtIndex:0

但该方法不能获取tmp文件夹的路径 // 获取tmp文件夹的路径
NSString *tmpPathStr = NSTemporaryDirectory();

数据持久化

数据持久化是一块比较重要的知识点,方式有4种:直接写入本地(writeToFile),sqlite数据库,CoreData 和NSUserDefaults 。

   注意,归档和解档不是数据持久化的方式,它是一种编码方式

因为比较重要 内容比较多, 这里先介绍直接写入本地方法,分为简单对象写入本地与复杂对象写入本地

简单对象写入本地: // 1:我要知道存到哪里,所以需要一个文件夹的路径 NSString documentPathStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; // 2:我要知道要存什么,所以创建一条数据 NSString str = @"hello world"; // 3:我要知道我存的东西到底放在哪里,所以创建了一个路径,路径的终点就是存数据的文件 NSString *strPath = [documentPathStr stringByAppendingPathComponent:@"str.mp4"]; // 4:准备工作做好了,开始写入的操作 [str writeToFile:strPath atomically:YES encoding:NSUTF8StringEncoding error:nil];

读取: NSString *newStr = [NSString stringWithContentsOfFile:strPath encoding:NSUTF8StringEncoding error:nil];

注意:可直接写入本地的简单对象有NSString,NSArray,NSDictionary 和NSData四种类型,写入方法大同小异,都是以上四步。数组与字典的写入方式相同,但写入本地时与字符串所用的方式不同,字符串比数组和字典多了转码的过程,读取时也需进入转码操作

数组的存储方式 // 2:准备存储的数据 NSArray array = @[@"1", @"2", @"3"]; // 3:存在哪里 NSString arrayPath = [documentPathStr stringByAppendingPathComponent:@"array.plist"];
// 4.执行存储事件 [array writeToFile:arrayPath atomically:YES];

读取: NSArray *newArray = [NSArray arrayWithContentsOfFile:arrayPath];

还需要注意NSData写入本地的操作,NSData是用于存储二进制的数据类型。NSData类提供了一种简单的方式,它用来设置缓冲区、将文件的内容读入缓冲区,或将缓冲区的内容写到一个文件。 分为不变缓冲区(NSData类),和可变的缓冲区(NSMutableData类)。

以UIImage为例,UIImage写入本地和读取时要与NAData相互转换 通过UIImageJPEGRepresentation方法把图片转化成NSData

UIImage *image = [UIImage imageNamed:@"123"];

// 将UIImage类型对象转化成NSData类型的
// 第一个参数:转哪个UIImage类型的对象
// 第二个参数:压缩系数,越小压缩的越厉害
NSData *data = UIImageJPEGRepresentation(image, 1);

UIImage类有initWithData方法 NSData newData = [NSData dataWithContentsOfFile:dataFile];
UIImage 
newImage = [[UIImage alloc] initWithData:newData]; 其余步骤便与数组字典相同

复杂对象写入本地: 如果一个对象想直接写入本地,那么这个对象需要遵守NSCoding协议 以person类为例,创建一个person类,在.h文件里遵循NSCoding协议 在.m文件里实现归档,解档的方法 // 归档 // 在归档和解档的时候,要把所有的属性都进行归解档

  • (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:self.name forKey:@"name"]; [coder encodeObject:self.gender forKey:@"gender"]; [coder encodeInteger:self.age forKey:@"age"]; }

// 解档

  • (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super init]; if (self) { self.name = [aDecoder decodeObjectForKey:@"name"]; self.gender = [aDecoder decodeObjectForKey:@"gender"]; self.age = [aDecoder decodeIntegerForKey:@"age"]; } return self; }

之后在controller里开始进行本地化操作 还要使用简单对象写入本地那四步操作,在第二步与第三步之间插入四步

//1. NSString documentPathStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]; //2
Person 
person = [[Person alloc] init];

person.name = @"班长";
person.gender = @"男";
person.age = 38;

// 将复杂对象归档之后存入本地(插入的四步)
// 第一步 : 创建一个NSMutableData,用于初始化归档工具
NSMutableData *data = [NSMutableData data];
// 第二步 : 创建一个归档工具
NSKeyedArchiver *keyedArchiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// 第三步 :使用归档工具 对需要归档的对象进行归档
[keyedArchiver encodeObject:person forKey:@"person"];
// 第四步 :结束归档
[keyedArchiver finishEncoding];

//注意 只有结束解档才能真正完成归档,获得对象 //3. NSString *mutableDataPath = [documentPathStr stringByAppendingPathComponent:@"person.plist"]; //4. [data writeToFile:mutableDataPath atomically:YES];

pragma mark- 解档并使用

// 第一步 : 从本地获取到Data
NSData *newData = [NSData dataWithContentsOfFile:mutableDataPath];
// 第二步 : 通过获取到的data 创建一个解档工具
NSKeyedUnarchiver *keyedUnarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:newData];
// 第三步 : 创建一个person对象,接收解档结果
Person *newPerson = [keyedUnarchiver decodeObjectForKey:@"person"];
// 第四步 : 结束解档
[keyedUnarchiver finishDecoding];
原文地址:https://www.cnblogs.com/guiyangxueyuan/p/5330453.html