<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];```
-----------------------

------------------
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
- 在一個路徑下存數據,最后一次存進去的東西會覆蓋之前的