數(shù)據(jù)存儲
- iOS應(yīng)用數(shù)據(jù)存儲的常用方式撤师?
- XML屬性列表(plist)歸檔(歸檔:用某種格式來保存一個或者多個對象古拴,以便以后還原這些對象氓润,是一個過程)罢荡。
- Preference(偏好設(shè)置),本質(zhì)還是通過“plist”來存儲數(shù)據(jù)紧索,但是使用更簡單(無需關(guān)注文件袁辈、文件夾路徑和名稱)。
- NSKeyedArchiver歸檔(NSCoding)珠漂,把任何對象直接保存為文件的方式吵瞻。
- SQLite3當(dāng)非常大量的數(shù)據(jù)存儲時使用葛菇。
- Core Data就是對SQLite的封裝。
- 應(yīng)用沙盒橡羞?
- app的沙盒:app可以保存一些自己的數(shù)據(jù)眯停;app的Bundle:應(yīng)用程序的安裝目錄。
- 應(yīng)用沙盒sandbox:每個iOS應(yīng)用都有自己的應(yīng)用沙盒卿泽,就是應(yīng)用的文件夾莺债,與其他文件系統(tǒng)隔離。應(yīng)用必須待在自己的沙盒里签夭,其他應(yīng)用不能訪問該沙盒齐邦。
- 應(yīng)用沙盒結(jié)構(gòu)分析:
- 應(yīng)用程序包:包含了所以的資源文件和可執(zhí)行文件。
- Documents:保存應(yīng)用運行時生成的需要持久化的數(shù)據(jù)第租,iTunes同步設(shè)備會備份該目錄措拇。保存相對重要的數(shù)據(jù)。
- tmp:保存應(yīng)用運行時所需的臨時數(shù)據(jù)慎宾,使用完畢后再將相應(yīng)的文件從該目錄刪除丐吓。應(yīng)用沒有運行時,系統(tǒng)也可能會清除該目錄下的文件趟据。iTunes同步設(shè)備時不會備份該目錄券犁。保存不重要的并且大的數(shù)據(jù)。
- Library/Caches:保存應(yīng)用運行時生成的需要持久化的數(shù)據(jù)汹碱,iTunes同步設(shè)備時不會備份該目錄粘衬。一般存儲體積大、不需要備份的非重要數(shù)據(jù)咳促。
- Library/Preference:保存應(yīng)用的所有偏好設(shè)置稚新,iOS的setting(設(shè)置)應(yīng)用會在該目錄中查找應(yīng)用的設(shè)置信息。iTunes同步設(shè)備時會備份該目錄跪腹。該目錄由系統(tǒng)管理褂删,無需我們來管理。通常用來存儲一些基本的軟件配置信息尺迂。
- 應(yīng)用沙盒目錄的常見獲取方式?
// 利用沙盒根目錄拼接”Documents”字符串
// 不建議采用冒掌,因為新版本的操作系統(tǒng)可能會修改目錄名
// 沙盒根目錄
NSString *home = NSHomeDirectory();
NSString *documents = [home stringByAppendingPathComponent:@"Documents"];
// 利用NSSearchPathForDirectoriesInDomains函數(shù)
// NSUserDomainMask 代表從用戶文件夾下找
// YES 代表展開路徑中的波浪字符“~”
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// 在iOS中噪裕,只有一個目錄跟傳入的參數(shù)匹配,所以這個集合里面只有一個元素
NSString *documents = [array objectAtIndex:0];
// 獲取tmp文件夾路徑
NSString *tmp = NSTemporaryDirectory();
- 屬性列表股毫?
- 屬性列表是一種XML格式的文件膳音,拓展名為plist。
- 如果對象是NSString铃诬、NSDictionary祭陷、NSArray苍凛、NSData、NSNumber等類型兵志,就可以使用
writeToFile:atomically:
方法直接將對象寫到屬性列表文件中醇蝴。 -
屬性列表-NSDictionary的存儲和讀取過程:
NSDictionary的存儲和讀取過程
- 偏好設(shè)置?
- 每個應(yīng)用都有個NSUserDefaults實例想罕,通過它來存取偏好設(shè)置悠栓。
- 注意:NSUserDefaults設(shè)置數(shù)據(jù)時,不是立即寫入按价,而是根據(jù)時間戳定時把緩存中的數(shù)據(jù)寫入本地磁盤惭适。所以調(diào)用了set方法之后數(shù)據(jù)有可能還沒有寫入磁盤應(yīng)用程序就終止了,因此楼镐,可以通過調(diào)用synchornize方法強制寫入癞志。
- 使用偏好設(shè)置不需關(guān)心文件名,直接通過NSUserDefaults操作框产,默認(rèn)就存到偏好設(shè)置里面了凄杯。通過NSUserDefaults就能直接訪問軟件的偏好設(shè)置(Library/Preferences)。
- 偏好設(shè)置底層實現(xiàn)原理:底層其實就是利用一個字典茅信,存儲一些鍵值對盾舌。
- 偏好設(shè)置好處:能快速存儲一些鍵值對;壞處:不能及時存儲蘸鲸,需要做同步操作妖谴,把內(nèi)存中的數(shù)據(jù)同步到硬盤上。
// 保存用戶是否自動登錄
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:YES forKey:@"auto_login"];
[defaults synchornize];
// 讀取保存的設(shè)置
BOOL autoLogin = [defaults boolForKey:@"auto_login"];
- NSKeyedArchiver膝舅?
- 如果對象是NSString、NSDictionary窑多、NSArray、NSData埂息、NSNumber等類型以及自定義對象類型,可以直接用NSKeyedArchiver進行歸檔和恢復(fù)千康。
- 不是所有的對象都可以直接用這種方法進行歸檔享幽,只有遵守了NSCoding協(xié)議的對象才可以值桩。
- NSCoding協(xié)議有2個方法:
-
encodeWithCoder:
每次歸檔對象時,都會調(diào)用這個方法豪椿。一般在這個方法里面指定如何歸檔對象中的每個實例變量携栋,可以使用encodeObject:forKey:
方法歸檔實例變量。 -
initWithCoder:
每次從文件中恢復(fù)(解碼)對象時婉支,都會調(diào)用這個方法。一般在這個方法里面指定如何解碼文件中的數(shù)據(jù)為對象的實例變量磅摹,可以使用decodeObject:forKey
方法解碼實例變量。
-
- NSKeyedArchiver-歸檔對象的注意:
- 如果父類遵守了NSCoding協(xié)議霎奢,應(yīng)該在encodeWithCoder:方法中加上一句
[super encodeWithCode:encode];
確保繼承的實例變量也能被編碼户誓,即也能被歸檔。 - 如果父類遵守了NSCoding協(xié)議幕侠,應(yīng)該在
initWithCoder:
方法中加上一句self = [super initWithCoder:decoder];
確保繼承的實例變量也能被解碼帝美,即也能被恢復(fù)。 - 因此如果在storyboard使用自定義view,重寫initWithCoder方法晤硕,一定要調(diào)用
self = [super initWithCoder:decoder];
悼潭,因為只有系統(tǒng)才知道怎么解析storyboard,如果沒有調(diào)用舞箍,就解析不了這個文件舰褪。
- 如果父類遵守了NSCoding協(xié)議霎奢,應(yīng)該在encodeWithCoder:方法中加上一句
![數(shù)組的編碼解碼過程](http://i2.tietuku.com/af17cea5fac147fa.png)
數(shù)組的編碼解碼過程
歸檔(編碼)
Person *person = [[Person alloc] init];
person.name = @"xxx";
person.age = 27;
[NSKeyedArchiver archiveRootObject:person toFile:path];
恢復(fù)(解碼)
Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
- 補充?
- 通過block為自定義視圖傳值疏橄,為什么block屬性要使用copy來修飾占拍?
- 原因:默認(rèn)如果在block中使用了外部變量,那么數(shù)據(jù)是保存在棧區(qū)的捎迫,當(dāng)超出方法作用域后晃酒,方法中的局部變量就釋放了,所以當(dāng)調(diào)用block的時候窄绒,方法中的局部變量已經(jīng)釋放贝次,所以就無法訪問到了。通過使用copy關(guān)鍵字彰导,在進行block賦值的時候蛔翅,把block拷貝到了堆中存儲,所以當(dāng)局部的方法被釋放以后依然可以使用block訪問到原來方法中的變量位谋。
- 通過block為自定義視圖傳值疏橄,為什么block屬性要使用copy來修飾占拍?