iOS基础--沙盒-数据本地化-归解档-整理总结(1)

1523603-76127da20d250cc6.png
惜春长怕花开早,何况落红无数!<圆陆鲨>

<h1>沙盒机制:</h1>

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

注意:

  • 1: 每一个应用程序都会拥有一个应用程序沙盒

  • 2: 应用程序沙盒就是一个系统目录

  • 3: 所有的非代码文件都保存在这个地方比如图片, 声音, 属性列表(plist), sqlite数据库和文本文件等.

  • 独立: 不可能出现两个程序公用同一个沙盒

  • 封闭 : 每一个沙盒 都只能他自己的应用去使用(很少的有和其他的app交互的,iOS8部分开放访问也允许了用的并不多,应用程序向外请求或者接收数据都需要经过权限认证)

  • 安全 :沙盒有被删除的时效


1523603-a89b8513bfefbd73.png
查找某个应用的沙盒

第一种方式: 上图 点击左上面的 <big>前往</big>--> <big>按住Alt键</big> --><big>选中资源库</big> --> <big>选中Developer文件夹 </big> --> <big> CoreSimulator</big> --> <big>Devices</big> --> <big>模拟器路径</big>

1523603-daa2ded74a01e1c6.png
第一步:
1523603-af507f28ab21084b.png
第二步:

第二种方式: 上图:


<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>
    1. 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 步: 从本地获取到Data

     NSData  *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
  • 在一个路径下存数据,最后一次存进去的东西会覆盖之前的

PS:下一篇在详细写点归解档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值