ios應用數據存儲的經常使用方式:ios
XML屬性列表(plist)歸檔app
Preference(偏好設置)dom
NSKeyedArchiver歸檔(NSCoding)函數
SQLite字體
Core Dataatom
沙盒:spa
每一個 iOS 應用都有本身的應用沙盒 ( 應用沙盒就是文件系統目錄 ) ,與其餘文件系統隔離。應用必須待在本身的沙盒裏,其餘應用不能訪問該沙盒code
應用沙盒的文件系統目錄,以下圖所示(假設應用的名稱叫 Layer )對象
應用程序包 : ( 上圖中的 Layer) 包含了全部的資源文件和可執行文件遊戲
同步的數據能夠保證app更新時一直存在,可是app卸載以後仍是會清空的。
Documents :保存應用運行時生成的 須要持久化的數據 , iTunes 同步設備時 會備份 該目錄。例如,遊戲應用可將遊戲存檔保存在該目錄(備份就是更換設備數據也不丟失)
tmp :保存應用運行時所需的 臨時數據 ,使用完畢後再將相應的文件從該目錄刪除。應用沒有運行時,系統也可能會清除該目錄下的文件。 iTunes 同步設備時 不會備份 該目錄
Library/Caches :保存應用運行時生成的 須要持久化的數據 , iTunes 同步設備時 不會備份 該目錄。通常存儲體積大、不須要備份的非重要數據
Library/Preference :保存應用的全部 偏好設置 , iOS 的 Settings( 設置 ) 應用會在該目錄中查找應用的設置信息。 iTunes 同步設備時 會備份 該目錄
沙盒根目錄 : NSString *home = NSHomeDirectory ();
Documents :目錄
利用 NSSearchPathForDirectoriesInDomains 函數
FOUNDATION_EXPORT NSArray *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde);
directory參數:NSSearchPathDirectory類型的enum值,代表咱們要搜索的目錄名稱,好比這裏用NSDocumentDirectory代表咱們要搜索的是Documents目錄。若是咱們將其換成NSCachesDirectory就表示咱們搜索的是Library/Caches目錄。
domainMask參數:NSSearchPathDomainMask類型的enum值,指定搜索範圍,這裏的NSUserDomainMask表示搜索的範圍限制於當前應用的沙盒目錄。還能夠寫成NSLocalDomainMask(表示/Library)、NSNetworkDomainMask(表示/Network)等。
expandTilde參數:BOOL值,表示是否展開波浪線~。咱們知道在iOS中~的全寫形式是/User/userName,該值爲YES即表示寫成全寫形式,爲NO就表示直接寫成「~」
// 在iOS中,只有一個目錄跟傳入的參數匹配,因此這個集合裏面只有一個元素
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"test.plist"];
tmp : NSString * tmp = NSTemporaryDirectory ();
Library/ Caches : ( 跟 Documents 相似的 2 種方法 )
利用沙盒根目錄拼接 」Caches」 字符串
利用 NSSearchPathForDirectoriesInDomains 函數 ( 將函數的第 2 個參數改成: NSCachesDirectory 便可 )
Library/ Preference :經過 NSUserDefaults 類存取該目錄下的設置信息
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
屬性列表:
屬性列表是一種XML格式的文件,拓展名爲plist
若是對象是NSString、NSDictionary、NSArray、NSData、NSNumber等類型,就可使用writeToFile:atomically:方法直接將對象寫到屬性列表文件中
例:
// 將數據封裝成字典
NSMutableDictionary *dict =[NSMutableDictionary dictionary];
[dict setObject:@"母雞" forKey:@"name"];
[dict setObject:@"15013141314" forKey:@"phone"];
[dict setObject:@"27" forKey:@"age"];
// 將字典持久化到Documents/stu.plist文件中 (寫入)
[dict writeToFile:pathatomically:YES];
讀取屬性列表,恢復NSDictionary對象
// 讀取Documents/stu.plist的內容,實例化NSDictionary
NSDictionary *dict =[NSDictionary dictionaryWithContentsOfFile:path];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
偏好設置:
不少iOS應用都支持偏好設置,好比保存用戶名、密碼、字體大小等設置,iOS提供了一套標準的解決方案來爲應用加入偏好設置功能
每一個應用都有個NSUserDefaults實例,經過它來存取偏好設置
好比 , 保存用戶名、字體大小、是否自動登陸
//使用偏好設置保存數據 (寫)(修改:將對應的屬性再set一下)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//保存的數據
[defaults setObject:@"zhangsan" forKey:@"account"];
[defaults setObject:@"123" forKey:@"password"];
[defaults setBool:YES forKey:@"autoLogin"];
[defaults setBool:YES forKey:@"rememberPwd"];
//調用同步的方法,把數據保存到沙盒文件
[defaults synchronize];
————————————————————————————————
//讀取 用戶偏好設置 的數據 (讀)
NSUserDefaults *defautls = [NSUserDefaults standardUserDefaults];
NSString *account = [defautls objectForKey:@"account"];
NSString *password = [defautls objectForKey:@"password"];
BOOL rememberPwd = [defautls boolForKey:@"rememberPwd"];
BOOL autoLogin = [defautls boolForKey:@"autoLogin"];
----————————————————————————————————————————————————————————————————
//刪除 用戶偏好設置 數據 (刪除)
NSUserDefaults *defautls = [NSUserDefaults standardUserDefaults];
[defautls removeObjectForKey:@"account"];
//刪除記得也要調用 同步的方法
[defautls synchronize];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NSKeyedArchiver:
不是全部的對象均可以直接用這種方法進行歸檔, 只有遵照了 NSCoding協議 的對象才能夠
NSCoding 協議有 2 個方法:
encodeWithCoder :
每次歸檔對象時,都會調用這個方法。通常在這個方法裏面指定如何歸檔對象中的每一個實例變量,可使用encodeObject:forKey:方法歸檔實例變量
initWithCoder :
每次從文件中恢復(解碼)對象時,都會調用這個方法。通常在這個方法裏面指定如何解碼文件中的數據爲對象的實例變量,可使用decodeObject:forKey方法解碼實例變量
Contact *contact = [[Contact alloc] init];
contact.name = @"張三";
contact.age = 27;
contact.tel = @"13531232323";
// 歸檔
[NSKeyedArchiver archiveRootObject:contact toFile:self.plistPath];
//讀數據(解檔)
Contact *contact = [NSKeyedUnarchiver unarchiveObjectWithFile:self.plistPath];
runtime實現歸檔解檔:
#pragma 歸檔、解檔 - (void)encodeWithCoder:(NSCoder *)aCoder{ /* 獲取類中的ivar列表 count: count爲ivar總數 class_copyIvarList: 獲取類的所有屬性 **/ unsigned int count = 0; Ivar *ivarList = class_copyIvarList(self.class, &count); for (int i = 0; i< count; i++) { //取出Ivar Ivar ivar = ivarList[i]; //屬性名稱 ivar_getName:獲取類實例成員變量,只能取到本類的,父類的訪問不到 NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)]; //歸檔 經過KVC取的 就沒有int類型了 [aCoder encodeObject:[self valueForKey:key] forKey:key]; } //但凡在C語言裏面 看到New Creat Copy 都須要釋放 free(ivarList); //釋放 } - (instancetype)initWithCoder:(NSCoder *)coder{ if ( self = [super init]) { unsigned int count = 0; Ivar *ivarList = class_copyIvarList(self.class, &count); for (int i = 0; i< count; i++) { //取出Ivar Ivar ivar = ivarList[i]; //屬性名稱 NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)]; //解檔 設置到成員變量上 [self setValue: [coder decodeObjectForKey:key] forKey:key]; } free(ivarList); //釋放 } return self; }