對于NSUserDefault,做過iOS開發(fā)的人肯定不會陌生,它就是持久化數(shù)據(jù)的一種方式,主打輕量級的用戶配置信息。下面主要從三個方面來講講NSUserDefault:
1、基礎概念及用法
它是單例的,并且是線程安全的,是以鍵值對的形式保存在沙盒中,最下面還是用plist文件進行保存。支持存儲的數(shù)據(jù)類型是id,NSObject(自定義對象),NSString,NSNumber,NSArray,NSDictionary,NSData。
在進行自定義對象的歸檔時需要實現(xiàn)NSCoding協(xié)議,不實現(xiàn)協(xié)議方法則拋出異常,類似于序列化與反序列話,獲得的對象都是不一致的。在Java中可以做到對象的一致性,有serializableUID的概念,在iOS不知如何做到,知道的可以告知。
對其他幾類對象,無論是可變類型還是不可變類型,最終取出來的數(shù)據(jù)都是不可變的。
雖然在提供的API中有

這幾個方法,但是系統(tǒng)在后臺保存數(shù)據(jù)的數(shù)據(jù)都轉(zhuǎn)化為NSNumber對象,對于取數(shù)據(jù)也有對應的方法

系統(tǒng)在后臺也做了處理,如果直接用objectForKey:取出的內(nèi)容是NSNumber類型,需要進一步轉(zhuǎn)換。
2、是如何進行數(shù)據(jù)保存的
用它進行數(shù)據(jù)保存時,如果你設置或刪除了值,如果沒有手動調(diào)用synchronize方法則有可能取不到剛設置或刪除的值,在項目開發(fā)過程中遇到這種現(xiàn)象比較普遍。而系統(tǒng)的做法也是定時的調(diào)用此方法。
3、域的概念以及其用法
在NSUserDefault中存在域的概念,包含5個部分NSArgumentDomain,Application,NSGlobalDomain,Languages,NSRegistrationDomain。
NSArgumentDomain:代表的是命令行參數(shù),可以在Edit Scheme->Arguments->Arguments Passed On Launch中添加,格式是-key value。
Application:應用程序域,設置的方法默認數(shù)據(jù)保存是在這里
NSGlobalDomain:全局域,所有應用程序都將公用該域
Languages:國際化語言版本域
NSRegistrationDomain:臨時域,- (void)registerDefaults:(NSDictionary*)registrationDictionary方法被調(diào)用是數(shù)據(jù)是保存在這里。
在讀取數(shù)據(jù)時,都會在底層的存儲結(jié)構(gòu)中進行一次搜索,搜索的順序是這樣:
NSArgumentDomain->Application->NSGlobalDomain->Languages->NSRegistrationDomain
寫了個測試:


這5是哪里輸出來的呢?我是在NSArgumentDomain中設置了

知道了NSUserDefault讀取數(shù)據(jù)的搜索順序,就可以做一些實際運用。比如要測試國際化的版本,因NSArgumentDomain比Languages更先搜索到,所以可以設置-AppleLanguages (zh-Hans),就不用頻繁的切換模擬器的語言版本來測試國際化了。