iOS基礎(chǔ)--沙盒-數(shù)據(jù)本地化-歸解檔-整理總結(jié)(1)

惜春長(zhǎng)怕花開早,何況落紅無(wú)數(shù)!<圓陸鯊>

<h1>沙盒機(jī)制:</h1>

沙盒 : 每個(gè)iOS應(yīng)用程序都會(huì)為自己創(chuàng)建一個(gè)文件系統(tǒng)目錄(文件夾),這個(gè)<big>獨(dú)立,封閉,安全</big>的空間 ,叫做沙盒 ,是一種安全體系.

注意:

  • 1: 每一個(gè)應(yīng)用程序都會(huì)擁有一個(gè)應(yīng)用程序沙盒

  • 2: 應(yīng)用程序沙盒就是一個(gè)系統(tǒng)目錄

  • 3: 所有的非代碼文件都保存在這個(gè)地方比如圖片, 聲音, 屬性列表(plist), sqlite數(shù)據(jù)庫(kù)和文本文件等.

  • 獨(dú)立: 不可能出現(xiàn)兩個(gè)程序公用同一個(gè)沙盒

  • 封閉 : 每一個(gè)沙盒 都只能他自己的應(yīng)用去使用(很少的有和其他的app交互的,iOS8部分開放訪問(wèn)也允許了用的并不多,應(yīng)用程序向外請(qǐng)求或者接收數(shù)據(jù)都需要經(jīng)過(guò)權(quán)限認(rèn)證)

  • 安全 :沙盒有被刪除的時(shí)效


查找某個(gè)應(yīng)用的沙盒

第一種方式: 上圖 點(diǎn)擊左上面的 <big>前往</big>--> <big>按住Alt鍵</big> --><big>選中資源庫(kù)</big> --> <big>選中Developer文件夾 </big> --> <big> CoreSimulator</big> --> <big>Devices</big> --> <big>模擬器路徑</big>

第一步:
第二步:

第二種方式: 上圖:


<h2>文件夾:</h2>

  • <u><h4>Documents</h4></u> :
    1: 存入一些永遠(yuǎn)不被刪除的文件(不會(huì)被系統(tǒng)主動(dòng)刪除),itunes備份時(shí),同時(shí)也會(huì)備份Documents文件(條件: 盡量不在Documents放入音頻視頻等太大的東西,只放一些重要文件,以免審核被拒) 注 :可以存,有方法讓審核通過(guò)
  • <u><h4>Documents下的inbox文件</h4></u>: 該文件是用來(lái)保存其他應(yīng)用程序請(qǐng)求,在當(dāng)前應(yīng)用程序打開的文件 例如: 應(yīng)用 A 中有一個(gè)文件,可以被應(yīng)用B打開.那么應(yīng)用B就創(chuàng)建一個(gè)文件 C 去保存 A 中可被 B 打開的文件 (將A的文件復(fù)制到C 中),再讓 B 打開 A中的文件,而這個(gè) C 就是inbox文件. (例如微信中打開網(wǎng)頁(yè)).
  • <u><h4>Library</h4></u>
    1. Caches : 存儲(chǔ)緩存的文件夾 當(dāng)用戶對(duì)某一個(gè)URL做請(qǐng)求操作的時(shí)候,這個(gè)URL里面的東西會(huì)保存在主機(jī)里面的某個(gè)位置 . Cookie 和Session . (itunes不會(huì)備份此目錄,文件不會(huì)再應(yīng)用退出時(shí)刪除,一般存放比較大,不是特別重要的資源)
  • 2: Preferences 保存應(yīng)用的所有偏好設(shè)置.iOS的Settings (夜間模式, 無(wú)圖模式, 淘寶登錄信息, 永久存儲(chǔ)是否或者去獲取地理位置) 應(yīng)用會(huì)該目錄中查找應(yīng)用的設(shè)置信息,iTunes會(huì)備份它, 注意: 不應(yīng)該直接創(chuàng)建偏好設(shè)置文件,而是應(yīng)該使用NSUserDefaults 類來(lái)取得和設(shè)置應(yīng)用程序的偏好 存儲(chǔ)的用戶數(shù)據(jù)都會(huì)保存在該目錄下的.plist文件中.,通常情況下由系統(tǒng)維護(hù) ,我們很少去操作.
  • <u><h4>tmp</h4></u> : 保存應(yīng)用運(yùn)行時(shí)所需的臨時(shí)數(shù)據(jù),使用完畢后會(huì)將相應(yīng)的文件從該目錄刪除.應(yīng)用沒(méi)有運(yùn)行時(shí)或者手機(jī)重啟時(shí) ,系統(tǒng)也有可能會(huì)清除該目錄下的文件,iTunes 不會(huì)同步該目錄
  • <u><h4>.app文件</h4></u> :該目錄包含了應(yīng)用程序的本身的數(shù)據(jù),包括資源文件和可執(zhí)行文件,程序啟動(dòng)后會(huì)根據(jù)需求動(dòng)態(tài)加載(懶加載)代碼 或者 資源到內(nèi)存中.而且整個(gè)目錄是只讀的. 不會(huì)被iTunes 同步

獲取文件夾方法:

  • 第一種: 通過(guò)該NSSeach搜索文件夾得地址,能獲取Documents 和Library 內(nèi)部文件夾地址, 但是不能獲取tmp文件夾得地址,其他的都可以獲取到.

    // NSDocumentDirectory 表示獲取Documents文件夾得地址
    // NSUserDomainMask 表示用戶的主目錄
    // 第三個(gè)參數(shù)表示 展開"~" 的地址,設(shè)置為YES 為完整路徑
    // NSSearchPathForDirectoriesInDomains獲取的是一個(gè)數(shù)組(NSArray<NSString *> *),數(shù)組只有一個(gè)元素,所以可以直接獲取objectAtIndex: 0 ;

NSString *documentPathStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSLog(@"%@",documentPathStr);
  • 第二種: 首先獲取沙盒主路徑的地址,然后拼接上想要去的文件夾的地址.

// 首先獲取沙盒主路徑的地址

NSString  *homePathStr = NSHomeDirectory();    NSLog(@"homePathStr = %@",homePathStr);```
// 其次: 在沙盒主路徑后拼接Documents,拼接出來(lái)documents文件夾的路徑
   ```code
 NSString *documentsPathStr = [homePathStr stringByAppendingPathComponent:@"Library/Caches"];
 NSLog(@"documents = %@",documentsPathStr);```
 //獲取tmp文件夾得路徑
 ```code
 NSString *tmpPathStr = NSTemporaryDirectory();
 NSLog(@"tmpPathStr = %@",tmpPathStr);

// 4.獲取.app文件: 該目錄包含了應(yīng)用程序的本身的數(shù)據(jù),包括資源文件和可執(zhí)行文件,程序啟動(dòng)后會(huì)根據(jù)需求動(dòng)態(tài)加載(懶加載)代碼 或者 資源到內(nèi)存中.而且整個(gè)目錄是只讀的. 不會(huì)被iTunes 同步

NSString *appPath = [[NSBundle mainBundle] resourcePath];
NSLog(@"appPath**右擊打開包內(nèi)容**%@",appPath);

簡(jiǎn)單對(duì)象的寫入與讀寫

<u>數(shù)據(jù)本地化: 簡(jiǎn)單說(shuō)就是把數(shù)據(jù)的,存儲(chǔ)到應(yīng)用程序的沙盒里面</u>

  • 寫入
    // 1 . 要知道存到哪里 ,所以需要一個(gè)文件夾的路徑
NSString  *documentsPathStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];    NSLog(@"%@",documentsPathStr);    ```
// 2 . 知道要存什么,  創(chuàng)建數(shù)據(jù)    
```code
NSString  *str = @"hello world";    ```
// 3 . 要知道數(shù)據(jù)放哪里 , 創(chuàng)建一個(gè)路徑,路徑的終點(diǎn)局勢(shì)存數(shù)據(jù)的文件 Component(成分)    
```code
NSString  *strPath = [documentsPathStr stringByAppendingPathComponent:@"str.txt"];   ```
 // 4 . 寫入操作    
```obj 
// 參數(shù): atomically : YES 正當(dāng)手機(jī)沒(méi)電關(guān)機(jī) 會(huì)保存文件   
 //              NO   否    
// encoding : 編碼方式    
[str writeToFile:strPath atomically:YES encoding:NSUTF8StringEncoding error:nil];```
   
-  讀取

    // 通過(guò)路徑讀取數(shù)據(jù),使用stringWithContentsOfFile方法,在讀取的時(shí)候,
```obj
參數(shù)1: 表示讀取文件的路徑,
參數(shù)2: 表示編碼格式,
參數(shù)3: 表示錯(cuò)誤信息.
NSString *newStr = [NSString stringWithContentsOfFile:strPath encoding:NSUTF8StringEncoding error:nil];```

-----------------------
![簡(jiǎn)單對(duì)象的寫入讀取方法](http://upload-images.jianshu.io/upload_images/1523603-f812d1715e502db8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

------------------
NSData數(shù)據(jù)讀取存儲(chǔ):
------------
題外話:
```obj 
UIImage *image1 = [UIImage imageNamed:<#(nonnull NSString *)#>]; 
UIImage *image2 = [UIImage alloc]initWithContentsOfFile:<#(nonnull NSString *)#>];````
- 根據(jù)imageName獲取圖片:會(huì)在緩存里存一份,下次在獲取同名圖片,直接從緩存里取.
 - 優(yōu)點(diǎn):快,只有第一次的時(shí)候慢,但是之后再獲取的話會(huì)很快.   
 - 缺點(diǎn):會(huì)浪費(fèi)內(nèi)存,如果只用致辭的話這塊內(nèi)存就浪費(fèi)掉了.   
- 根據(jù)ContentsOfFile獲取到的圖片:每次都會(huì)根據(jù)路徑去取圖片,不會(huì)占用內(nèi)存.如果圖片只使用一次,推薦使用ContentsOfFile    

#####寫入:
// 第一步: 獲取路徑

    NSString*documentPathStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)objectAtIndex:0];
// 第二步: 創(chuàng)建一個(gè)UIimag的數(shù)據(jù)并轉(zhuǎn)化成NSData類型的對(duì)象
```obj
     UIImage*image = [UIImage imageNamed:@"123"];
//將UIImage類型對(duì)象轉(zhuǎn)化成NSData類型的
//第一個(gè)參數(shù) :轉(zhuǎn)哪個(gè)UIImage類型對(duì)象
//第二個(gè)參數(shù):壓縮系數(shù),越小壓縮越厲害
    NSData *data =UIImageJPEGRepresentation(image, 1); ```
// 第三步: 拼接出最終的存儲(chǔ)地方
```obj
    NSString *stringPath = [documentPathStr stringByAppendingPathComponent:@"stringPath.txt" ];```
   
 // 第四步: 寫入
```obj
[data  writeToFile:stringPath atomically:YES];```
    
####讀取數(shù)據(jù):
```obj
// 創(chuàng)建一個(gè)NSData類型數(shù)據(jù) 從文件中找到
NSData *newData = [NSData dataWithContentsOfFile:stringPath];
// 再轉(zhuǎn)成UIImage
UIImage *newImage = [UIImage imageWithData:newData];

復(fù)雜對(duì)象的寫入與讀取:

復(fù)雜對(duì)象是指:

在Foundation框架內(nèi)不存在的數(shù)據(jù)類,如自定義Person類等 無(wú)法在程序內(nèi)通過(guò)writeToFile: 這個(gè)方法寫入文件內(nèi) 只能通過(guò)將負(fù)載對(duì)象轉(zhuǎn)化為NSData,即歸檔

  • 復(fù)雜對(duì)象寫入文件的過(guò)程:
    復(fù)雜對(duì)象---> 歸檔 ---> NSData --->writeToFile

  • 文件中讀取復(fù)雜對(duì)象的過(guò)程:
    讀取文件 ---> NSData --->反歸檔 --->復(fù)雜對(duì)象

  • 首先:復(fù)雜對(duì)象所屬的類要遵守 <NSCoding>協(xié)議

  • 其次:實(shí)現(xiàn)協(xié)議中的兩個(gè)方法:

  • (void)encodeWithCoder:(NSCoder *)aCoder;序列化
  • (id)initWithCoder:(NSCoder *)aDecoder:反序列化

--------------------
歸解檔:
--------------------

舉例建一個(gè)Person 類 有以下屬性
// 如果一個(gè)對(duì)象向直接寫入本地,那么這個(gè)對(duì)象需要遵守NSCoding協(xié)議
```obj
@interface Person : NSObject<NSCoding>
@property(nonatomic,copy)NSString * name;
@property(nonatomic,copy)NSString *gender;
@property(nonatomic,assign)NSUInteger  age;```

實(shí)現(xiàn)協(xié)議方法:
```obj
//歸檔
//在歸檔和解檔的時(shí)候,要把所有的屬性都進(jìn)行歸解檔
- (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;
}

上代碼:
// 如果一個(gè)對(duì)象向直接寫入本地,那么這個(gè)對(duì)象需要遵守NSCoding協(xié)議
// 建一個(gè)實(shí)例對(duì)象

Person *person = [[Person alloc]init]; 
person.name = @"James"; 
person.gender = @"M";
person.age = 38 ;
  • 歸檔
    //將復(fù)雜對(duì)象歸檔之后存入本地
    //第 1 步: 創(chuàng)建一個(gè)NSMutableData ,用于保存歸檔后的對(duì)象(初始化歸檔工具)

    NSMutableData *data = [NSMutableData data];
    

    //第 2 步: 創(chuàng)建個(gè)歸檔工具

     NSKeyedArchiver *keyedArchiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
    

    //第 3 步: 歸檔

     [keyedArchiver encodeObject:person forKey:@"person"];
    

    //第 4 步: 結(jié)束歸檔

    [keyedArchiver finishEncoding];
    

    //這時(shí)候存Data存儲(chǔ)好數(shù)據(jù)

     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 步: 通過(guò)獲取到的data 創(chuàng)建一個(gè)解檔工具

  NSKeyedUnarchiver *keyedUnarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:newData];   

//第 3 步:創(chuàng)建一個(gè)Person對(duì)象,接收解檔結(jié)果

   Person *newPerson = [keyedUnarchiver decodeObjectForKey:@"person"];   

//第 4 步:結(jié)束解檔

  [keyedUnarchiver finishDecoding];    
  NSLog(@"%@",newPerson);      
  • 歸解檔是一種編碼方式,不是數(shù)據(jù)本地化的方式
  • 負(fù)載對(duì)象寫入本地實(shí)際上使用的還是writeToFile 的簡(jiǎn)單寫入本地的方法
  • 整存整取 writeToFile
  • 在一個(gè)路徑下存數(shù)據(jù),最后一次存進(jìn)去的東西會(huì)覆蓋之前的

PS:下一篇在詳細(xì)寫點(diǎn)歸解檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容