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

惜春长怕花开早,何况落红无数!<圆陆鲨>

<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>
    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:下一篇在详细写点归解档

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容