
<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í)效

第一種方式: 上圖 點(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>
- 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];```
-----------------------

------------------
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 步: 從本地獲取到DataNSData *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ì)覆蓋之前的