沙盒文件以及沙盒文件路徑、和本地存儲

一、iOS中的沙盒機制

iOS應用程序只能對自己創建的文件系統讀取文件,這個獨立、封閉、安全的空間,叫做沙盒。每個ios應用都有自己的應用沙盒,應用沙盒就是文件系統目錄,與其他應用的文件系統隔離。它一般存放著程序包文件(可執行文件)、圖片、音頻、視頻、plist文件、sqlite數據庫以及其他文件。每個應用程序都有自己的獨立的存儲空間(沙盒)一般來說應用程序之間是不可以互相訪問的,在ios8中已經開放訪問,模擬器沙盒的位置路徑:/User/userName/Library/Application Support/iPhone Simulator;當我們創建應用程序時,在每個沙盒中含有三個文件,分別是Document、Library(下面有Caches和Preferences目錄)和temp。
應用程序包:包含所有的資源文件和可執行文件。

二、對Document、Library(下面有Caches和Preferences目錄)和temp做簡單介紹

1.Document:一般需要持久的數據都放在此目錄中,可以在當中添加子文件夾,iTunes備份和恢復的時候,會包括此目錄。

2.Library:設置程序的默認設置和其他狀態信息,iTunes會自動備份該目錄,例如雜志、新聞、地圖應用使用的數據庫緩存文件和可下載內容應該保存到這個文件夾。一般可以重新下載或者重新生成的數據應該保存在 <Application_Home>/Library/Caches 目錄下面。
Libaray/Caches:存放緩存文件,iTunes不會備份此目錄,此目錄下文件不會在應用退出刪除。一般存放體積比較大,不是特別重要的資源。
Libaray/PreferencePanes:保存應用的所有偏好設置,ios的Settings(設置)應用會在該目錄中查找應用的設置信息,iTunes會自動備份該目錄。

3.temp:創建臨時文件的目錄,當iOS設備重啟時,文件會被自動清除,只是臨時使用的數據應該保存到 <Application_Home>/tmp 文件夾。iCloud 不會備份這些文件,下次啟動應用自動刪除。

三、獲取沙盒路徑
//Home目錄  
NSString *homeDirectory = NSHomeDirectory();   
  
//Document目錄  
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);     
NSString *path = [paths objectAtIndex:0];     
  
//Cache目錄  
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);     
NSString *path = [paths objectAtIndex:0];     
  
//PreferencePanes目錄  
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSUserDomainMask, YES);  
NSString *path = [paths objectAtIndex:0];  
  
//Libaray目錄NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);     
NSString *path = [paths objectAtIndex:0];     
  
//tmp目錄   
NSString *tmpDir = NSTemporaryDirectory(); 
四、本地存儲
1、plist存儲
? 把一些系統自帶的OC對象生成pilst文件存儲起來。
1> 了解數據存儲:數據存儲一般有兩個操作,一個存,一個取。拖兩個按鈕,一個用來存,一個用來取
2> plist存儲原理:
? 只要有writeToFile的對象,就能進行plist存儲,調用writeToFile就能自動生成plist格式的文件。
? 一般常用的Foundation對象都有這個方法,數組,字典,字符串等
3> 如何寫入到沙盒,需要獲取沙盒路徑。
? 獲取Documents路徑
? 拼接文件名,因為數據是寫入到文件中,不是寫入到文件夾中。路徑之間通過/分開的,為了避免自己寫/,會用stringByAppendingPathCompent,自動在文件夾與文件之間添加/。
4> 如何讀取,存儲是什么類型存儲,讀取出來也是什么類型,直接用存儲的類型,解析文件就好,用ContentsOfFile解析。
5> 注意plist存儲,不能存儲自定義對象,會失敗的。
//    1.獲取home路徑
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [paths objectAtIndex:0];
//    2.拼接路徑創建plist文件
    NSString *docPath = [path stringByAppendingPathComponent:@"2.plist"];
//    3.創建一個數組,存儲數據到plist文件中
    NSArray *persons = @[@"zhangsan",@"lisi",@"王六"];
//    4.把數據寫入到文件中
   [ persons writeToFile:docPath atomically:YES];
//  5.讀取文件的內容(注意存的是什么,用什么格式接收)
    NSArray* readArray = [NSArray arrayWithContentsOfFile:docPath];
    NSLog(@"%@",readArray);
2、偏好設置
1> 什么是偏好設置存儲:就是保存一些基本的信息,賬號,密碼,狀態。
    2> 偏好設置原理:不需要關心文件名,直接通過NSUserDefaults操作,默認就存到偏好設置里面了。
    ? 通過NSUserDefaults就能直接訪問軟件的偏好設置(Library/Preferences)
    3> 怎么利用偏好設置存儲?利用NSUserDefaults調用setObject:forKey存儲。
    ? 偏好設置底層實現原理:底層其實就是利用一個字典,存儲一些鍵值對。
    ? 偏好設置好處:能快速存儲一些鍵值對,如果用字典去存儲,還需要獲取文件名比較麻煩。
    ? 偏好設置壞處:不能及時存儲,需要做同步操作,把內存中的數據同步到硬盤上。
    4> 怎么利用偏好設置讀取?和字典一樣,根據剛剛存儲的Key讀取。
//使用偏好設置(存儲數據)
//   1,獲取Default對象,通過這個對象來存儲數據
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
//    2.通過這個對象來存儲數據
    [userDefault setObject:@"zhangsan" forKey:@"name"];
    [userDefault setObject:@"163.com" forKey:@"email"];
    [userDefault setBool:YES forKey:@"gender"];
//    3.立即同步
    [userDefault synchronize];
//取數據
//    1.獲取Default對象
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
//    2.通過這個對象來讀取數據
    NSString *name =  [userDefault objectForKey:@"name"];
    NSString *email = [userDefault objectForKey:@"email"];
    BOOL gender = [userDefault boolForKey:@"gender"];
////    3.同步
    [userDefault synchronize];
    NSLog(@"%@----%@---%d",name,email,gender);
3、自定義對象歸檔(歸檔:數據存儲)

1> 自定義對象如何歸檔:用NSKeyedArchiver,調用archiveRootObject:toFile:方法,需要傳一個對象,自定義一個對象,傳進去。
? 會報錯,說對象沒有encodeWithCoder方法,說明歸檔的時候默認會調用這個方法,去實現這個方法。
? 默認打不出encodeWithCoder,必須遵守NSCoding協議才能實現這個方法。
? encodeWithCoder什么時候調用:對象歸檔時候調用
? encodeWithCoder作用:告訴系統對象里的哪些屬性需要歸檔,怎么去歸檔,根據一個key去歸檔,目的就是以后取的時候,也根據這個key去取數據。
2> 自定義對象如何解檔:用NSKeyedUnarchiver,調用unarchiveObjectWithFile方法,需要傳一個文件名。
? 會報錯,說對象沒有initWithCoder方法,說明解檔的時候默認會調用這個方法,去實現這個方法。
? initWithCoder什么時候調用:對象解檔時候調用
? initWithCoder作用:告訴系統對象里的哪些屬性需要解檔,怎么去解檔,根據之前存儲的key去解檔
? initWithCoder是一個初始化方法,需要先初始化父類的,但是不能調用[super initWithCoder:],因為父類NSObject沒有遵守NSCoding協議。
3> initWithCoder什么時候需要調用[super initWithCoder:]
? initWithCoder原理:只要解析文件就會調用,xib,storyboard都是文件,因此只要解析這兩個文件,就會調用initWithCoder。
? 因此如果在storyboard使用自定義view,重寫initWithCoder方法,一定要調用[super initWithCoder:],因為只有系統才知道怎么解析storyboard,如果沒有調用,就解析不了這個文件。

#import "HMPerson.h"

@implementation HMPerson
//用來告訴系統怎么來存儲數據(告訴系統各個字段怎么進行存儲)

- (void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.email forKey:@"email"];
    [aCoder encodeInteger:self.age forKey:@"age"];
    
}
//通過這個方法來實現怎么讀取數據
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super init]) {
       self.name =  [aDecoder decodeObjectForKey:@"name"];
        self.email = [aDecoder decodeObjectForKey:@"email"];
        self.age =  [aDecoder decodeIntForKey:@"age"];
    }
    return self;
    
}

@end
//點擊屏幕的時候就會調用這個方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
//  1.創建對象
    HMPerson *person = [[HMPerson alloc]init];
    person.name = @"zhansan";
    person.email = @"1234@qq.com";
    person.age = 30;
//    2.存儲對象(通過NSKeyedArchiver存儲數據)
    [NSKeyedArchiver archiveRootObject:person toFile:[self getDataPath]];
//    3.讀取數據
    [self readData];
    
    
}
//讀取數據
- (void)readData{
   HMStudent *student = [NSKeyedUnarchiver unarchiveObjectWithFile:[self getDataPath]];
    NSLog(@"%@---%@--%d--%@",student.name,student.email,student.age,student.studentId);
    
    
}

- (NSString *)getDataPath{
//    1.獲取路徑
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
    
//    2.拼接路徑
    NSString *dataPath = [docPath stringByAppendingPathComponent:@"student.data"];
    
//
    NSLog(@"%@",dataPath);
    return dataPath;
    
    
    
}
//歸檔成二進制數據,然后進行偏好設置存儲二進制數據
NSData * normalData = [NSKeyedArchiver archivedDataWithRootObject:normalTempArray];
        
[ud setObject:normalData forKey:@"normalPlaneCity"];
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容