<h1>沙盒机制:</h1>
沙盒 : 每个iOS应用程序都会为自己创建一个文件系统目录(文件夹),这个<big>独立,封闭,安全
</big>的空间 ,叫做沙盒 ,是一种安全体系.
注意:
1: 每一个应用程序都会拥有一个应用程序沙盒
2: 应用程序沙盒就是一个系统目录
3: 所有的非代码文件都保存在这个地方比如图片, 声音, 属性列表(plist), sqlite数据库和文本文件等.
独立: 不可能出现两个程序公用同一个沙盒
封闭 : 每一个沙盒 都只能他自己的应用去使用(很少的有和其他的app交互的,iOS8部分开放访问也允许了用的并不多,应用程序向外请求或者接收数据都需要经过权限认证)
安全 :沙盒有被删除的时效
第一种方式: 上图 点击左上面的 <big>前往</big>--> <big>按住Alt键</big> --><big>选中资源库</big> --> <big>选中Developer文件夹 </big> --> <big> CoreSimulator</big> --> <big>Devices</big> --> <big>模拟器路径</big>
第二种方式: 上图:
<h2>文件夹:</h2>
- <u><h4>Documents</h4></u> :
1: 存入一些永远不被删除的文件(不会被系统主动删除),itunes备份时,同时也会备份Documents文件(条件: 尽量不在Documents放入音频视频等太大的东西,只放一些重要文件,以免审核被拒) 注 :可以存,有方法让审核通过
- <u><h4>Documents下的inbox文件</h4></u>: 该文件是用来保存其他应用程序请求,在当前应用程序打开的文件 例如: 应用 A 中有一个文件,可以被应用B打开.那么应用B就创建一个文件 C 去保存 A 中可被 B 打开的文件 (将A的文件复制到C 中),再让 B 打开 A中的文件,而这个 C 就是inbox文件. (例如微信中打开网页).
- <u><h4>Library</h4></u>
- Caches : 存储缓存的文件夹 当用户对某一个URL做请求操作的时候,这个URL里面的东西会保存在主机里面的某个位置 . Cookie 和Session . (itunes不会备份此目录,文件不会再应用退出时删除,一般存放比较大,不是特别重要的资源)
- 2: Preferences 保存应用的所有偏好设置.iOS的Settings (夜间模式, 无图模式, 淘宝登录信息, 永久存储是否或者去获取地理位置) 应用会该目录中查找应用的设置信息,iTunes会备份它, 注意: 不应该直接创建偏好设置文件,而是应该使用
NSUserDefaults 类
来取得和设置应用程序的偏好 存储的用户数据都会保存在该目录下的.plist文件中.,通常情况下由系统维护 ,我们很少去操作.
- <u><h4>tmp</h4></u> : 保存应用运行时所需的临时数据,使用完毕后会将相应的文件从该目录删除.应用没有运行时或者手机重启时 ,系统也有可能会清除该目录下的文件,iTunes 不会同步该目录
- <u><h4>.app文件</h4></u> :该目录包含了应用程序的本身的数据,包括资源文件和可执行文件,程序启动后会根据需求动态加载(懒加载)代码 或者 资源到内存中.而且整个目录是只读的. 不会被iTunes 同步
获取文件夹方法:
-
第一种: 通过该NSSeach搜索文件夹得地址,能获取Documents 和Library 内部文件夹地址, 但是不能获取tmp文件夹得地址,其他的都可以获取到.
// NSDocumentDirectory 表示获取Documents文件夹得地址
// NSUserDomainMask 表示用户的主目录
// 第三个参数表示 展开"~" 的地址,设置为YES 为完整路径
// NSSearchPathForDirectoriesInDomains获取的是一个数组(NSArray<NSString *> *),数组只有一个元素,所以可以直接获取objectAtIndex: 0 ;
NSString *documentPathStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSLog(@"%@",documentPathStr);
- 第二种: 首先获取沙盒主路径的地址,然后拼接上想要去的文件夹的地址.
// 首先获取沙盒主路径的地址
NSString *homePathStr = NSHomeDirectory(); NSLog(@"homePathStr = %@",homePathStr);```
// 其次: 在沙盒主路径后拼接Documents,拼接出来documents文件夹的路径
```code
NSString *documentsPathStr = [homePathStr stringByAppendingPathComponent:@"Library/Caches"];
NSLog(@"documents = %@",documentsPathStr);```
//获取tmp文件夹得路径
```code
NSString *tmpPathStr = NSTemporaryDirectory();
NSLog(@"tmpPathStr = %@",tmpPathStr);
// 4.获取.app文件: 该目录包含了应用程序的本身的数据,包括资源文件和可执行文件,程序启动后会根据需求动态加载(懒加载)代码 或者 资源到内存中.而且整个目录是只读的. 不会被iTunes 同步
NSString *appPath = [[NSBundle mainBundle] resourcePath];
NSLog(@"appPath**右击打开包内容**%@",appPath);
简单对象的写入与读写
<u>数据本地化: 简单说就是把数据的,存储到应用程序的沙盒里面</u>
- 写入
// 1 . 要知道存到哪里 ,所以需要一个文件夹的路径
NSString *documentsPathStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]; NSLog(@"%@",documentsPathStr); ```
// 2 . 知道要存什么, 创建数据
```code
NSString *str = @"hello world"; ```
// 3 . 要知道数据放哪里 , 创建一个路径,路径的终点局势存数据的文件 Component(成分)
```code
NSString *strPath = [documentsPathStr stringByAppendingPathComponent:@"str.txt"]; ```
// 4 . 写入操作
```obj
// 参数: atomically : YES 正当手机没电关机 会保存文件
// NO 否
// encoding : 编码方式
[str writeToFile:strPath atomically:YES encoding:NSUTF8StringEncoding error:nil];```
- 读取
// 通过路径读取数据,使用stringWithContentsOfFile方法,在读取的时候,
```obj
参数1: 表示读取文件的路径,
参数2: 表示编码格式,
参数3: 表示错误信息.
NSString *newStr = [NSString stringWithContentsOfFile:strPath encoding:NSUTF8StringEncoding error:nil];```
-----------------------
![简单对象的写入读取方法](http://upload-images.jianshu.io/upload_images/1523603-f812d1715e502db8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
------------------
NSData数据读取存储:
------------
题外话:
```obj
UIImage *image1 = [UIImage imageNamed:<#(nonnull NSString *)#>];
UIImage *image2 = [UIImage alloc]initWithContentsOfFile:<#(nonnull NSString *)#>];````
- 根据imageName获取图片:会在缓存里存一份,下次在获取同名图片,直接从缓存里取.
- 优点:快,只有第一次的时候慢,但是之后再获取的话会很快.
- 缺点:会浪费内存,如果只用致辞的话这块内存就浪费掉了.
- 根据ContentsOfFile获取到的图片:每次都会根据路径去取图片,不会占用内存.如果图片只使用一次,推荐使用ContentsOfFile
#####写入:
// 第一步: 获取路径
NSString*documentPathStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)objectAtIndex:0];
// 第二步: 创建一个UIimag的数据并转化成NSData类型的对象
```obj
UIImage*image = [UIImage imageNamed:@"123"];
//将UIImage类型对象转化成NSData类型的
//第一个参数 :转哪个UIImage类型对象
//第二个参数:压缩系数,越小压缩越厉害
NSData *data =UIImageJPEGRepresentation(image, 1); ```
// 第三步: 拼接出最终的存储地方
```obj
NSString *stringPath = [documentPathStr stringByAppendingPathComponent:@"stringPath.txt" ];```
// 第四步: 写入
```obj
[data writeToFile:stringPath atomically:YES];```
####读取数据:
```obj
// 创建一个NSData类型数据 从文件中找到
NSData *newData = [NSData dataWithContentsOfFile:stringPath];
// 再转成UIImage
UIImage *newImage = [UIImage imageWithData:newData];
复杂对象的写入与读取:
复杂对象是指:
在Foundation框架内不存在的数据类,如自定义Person类等 无法在程序内通过writeToFile: 这个方法写入文件内 只能通过将负载对象转化为NSData,即归档
复杂对象写入文件的过程:
复杂对象---> 归档 ---> NSData --->writeToFile文件中读取复杂对象的过程:
读取文件 ---> NSData --->反归档 --->复杂对象首先:复杂对象所属的类要遵守
<NSCoding>协议
其次:实现协议中的两个方法:
- (void)encodeWithCoder:(NSCoder *)aCoder;序列化
- (id)initWithCoder:(NSCoder *)aDecoder:反序列化
--------------------
归解档:
--------------------
举例建一个Person 类 有以下属性
// 如果一个对象向直接写入本地,那么这个对象需要遵守NSCoding协议
```obj
@interface Person : NSObject<NSCoding>
@property(nonatomic,copy)NSString * name;
@property(nonatomic,copy)NSString *gender;
@property(nonatomic,assign)NSUInteger age;```
实现协议方法:
```obj
//归档
//在归档和解档的时候,要把所有的属性都进行归解档
- (void)encodeWithCoder:(NSCoder*)aCoder
{
[aCoder encodeObject:self.nameforKey:@"name"];
[aCoder encodeObject:self.genderforKey:@"gender"];
[aCoder encodeInteger:self.ageforKey:@"age"];
}
//解档
- (instancetype)initWithCoder:(NSCoder*)aDecoder
{
if(self= [super init]) {
self.name= [aDecoder decodeObjectForKey:@"name"];
self.gender= [aDecoder decodeObjectForKey:@"gender"];
self.age= [aDecoder decodeIntegerForKey:@"age"];}
returnself;
}
上代码:
// 如果一个对象向直接写入本地,那么这个对象需要遵守NSCoding协议
// 建一个实例对象
Person *person = [[Person alloc]init];
person.name = @"James";
person.gender = @"M";
person.age = 38 ;
-
归档
//将复杂对象归档之后存入本地
//第 1 步: 创建一个NSMutableData ,用于保存归档后的对象(初始化归档工具)NSMutableData *data = [NSMutableData data];
//第 2 步: 创建个归档工具
NSKeyedArchiver *keyedArchiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
//第 3 步: 归档
[keyedArchiver encodeObject:person forKey:@"person"];
//第 4 步: 结束归档
[keyedArchiver finishEncoding];
//这时候存Data存储好数据
NSLog(@"data = %@",data);
//获取,拼接写入沙盒路径
NSString *documentPathStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]; NSString *dataPath = [documentPathStr stringByAppendingPathComponent:@"person.plist"] ;
// 写入
[data writeToFile:dataPath atomically:YES];
-
解档并使用
//第 1 步: 从本地获取到DataNSData *newData = [NSData dataWithContentsOfFile:dataPath]; NSLog(@"%@",newData);
//第 2 步: 通过获取到的data 创建一个解档工具
NSKeyedUnarchiver *keyedUnarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:newData];
//第 3 步:创建一个Person对象,接收解档结果
Person *newPerson = [keyedUnarchiver decodeObjectForKey:@"person"];
//第 4 步:结束解档
[keyedUnarchiver finishDecoding];
NSLog(@"%@",newPerson);
- 归解档是一种编码方式,不是数据本地化的方式
- 负载对象写入本地实际上使用的还是writeToFile 的简单写入本地的方法
- 整存整取 writeToFile
- 在一个路径下存数据,最后一次存进去的东西会覆盖之前的