在iOS開發(fā)當(dāng)中上渴,我們難免會遇到保存數(shù)據(jù)的情況蝉稳,即數(shù)據(jù)的本地永久存儲挚赊。其中,NSUserDefaults是最常使用的輕量級的數(shù)據(jù)存儲方式。今天小編就來簡單談一下NSUserDefaults跪者。
? ? 相信是個iOS程序猿都使用過NSUserDefaults來保存數(shù)據(jù),因為實(shí)在是太過簡單熄求,只需要使用使用兩行代碼就能保存了渣玲,如下:
使用NSUserDefaults來存取數(shù)據(jù)代碼非常簡單,但是很多人卻并不知道蘋果內(nèi)部是如何保存這個key-value的弟晚。這里就簡單來說一下:iOS系統(tǒng)是以一個.plist文件來統(tǒng)一管理這些使用NSUserDefaults保存的key-value的忘衍。大家可以參考你所在項目中的info.plist.
當(dāng)然,我們可以驗證一下:在代碼當(dāng)中執(zhí)行NSHomeDirectory()并打印卿城,復(fù)制枚钓,然后在Finder->前往->前往文件夾中粘貼前往,或者在終端中執(zhí)行"cd 剛才復(fù)制的路徑"->"open ."來前往所在沙河路徑瑟押。其中NSUserDefaults就保存在/Library/Preference中搀捷。
下面就看一下我一個demo中的plist文件:
從圖2當(dāng)中的.plist文件可以看到其與工程當(dāng)中的info.plist文件是一樣的,同時還要說一些題外話多望,那就是NSUserDefaults還有一些別的知識點(diǎn)嫩舟,比如圖2中的suitename等,詳情請參考文檔怀偷,這里不詳細(xì)解釋家厌。
說使用NSUserDefaults大家都會用,但是像圖1那樣寫代碼實(shí)在是太惡心了椎工,因為這個樣子寫數(shù)據(jù)根本沒有統(tǒng)一規(guī)劃饭于,而且取值的時候十分不方便。
比如做視頻播放器時常用到的下面這個:
根據(jù)圖3的顯示可以知道需求:當(dāng)UISwitch關(guān)閉時不允許播放視頻维蒙。這是一個很常見的產(chǎn)品需求掰吕,但是如果按照圖1的方式來寫,那豈不是要在很多地方寫[userDefaults objectForKey:@"key"]木西?所以畴栖,我們應(yīng)摒棄像圖1的那種方式使用NSUserDefaults。
當(dāng)然八千,也有很多人想到了別的方法來解決圖1那樣寫代碼所帶來的困擾吗讶,比如創(chuàng)建一個類文件來聲明所有的key值等!但是那樣子也難免有些麻煩恋捆,代碼寫起來也有些繁瑣照皆。
現(xiàn)在小編就來說說我的解決辦法:NSUserDefaults+單例+runtime。我寫的這個東西已經(jīng)上傳到Github沸停,項目名稱為UDUserDefaultsModel膜毁,并可以支持Cocoapods。
廢話不多說,我這里就來解釋UDUserDefaultsModel的思想以及用法:
1.UDUserDefaultsModel是一個單例瘟滨,可以實(shí)現(xiàn)App內(nèi)部各個類之間的數(shù)據(jù)共享候醒。
2.繼承自UDUserDefaultsModel創(chuàng)建一個子類,比如LCUserDefaultsModel杂瘸,并在.h文件中聲明一些屬性倒淫,這些屬性就是作為plist文件的key值存在的,如下:
3.在.m文件當(dāng)中對每一個屬性進(jìn)行@dynamic操作败玉,意為setter與getter方法由類自己實(shí)現(xiàn)敌土,如下:
4.如果想對屬性設(shè)置默認(rèn)值,那么需要重寫setupDefaultValues方法运翼,如下:
其中返干,圖6字典的規(guī)則是@{@"屬性的字符串": @"默認(rèn)值"}
5.以“name”來說,如果想要進(jìn)行取值的話只需要調(diào)用[LCUserDefaultsModel userDefaultsModel].name就行血淌,對"name"進(jìn)行更改并保存到plist文件的話只需要調(diào)用[LCUserDefaultsModel userDefaultsModel].name = @"newName"就可以了矩欠。
其實(shí)說到UDUserDefaultsModel這個小型的替代系統(tǒng)NSUserDefaults的第三方庫實(shí)現(xiàn)原理是:基于Objective-C的Runtime機(jī)制來重寫UDUserDefaultsModel子類的屬性方法,即Setter方法與Getter方法六剥,以達(dá)到一一映射晚顷。UDUserDefaultsModel用到的Runtime的方法有:
1.objc_property_t,property_getName和property_getAttributes這三個方法是用來獲取屬性Property的相關(guān)信息疗疟。
2.class_addMethod是為對象增加方法该默,也就是屬性的Setter與Getter方法。
代碼小編已上傳到Github策彤,項目名稱為UDUserDefaultsModel栓袖,并可以支持Cocoapods,歡迎大家支持店诗。捎帶說一句:別吝嗇你手里的星星裹刮。
(注:小編已根據(jù)同樣的思想來實(shí)現(xiàn)FMDB數(shù)據(jù)庫的存取,文章鏈接:iOS-FMDB改進(jìn)方案YIIFMDB:直接操作Model,純面向?qū)ο笈尤常恍枰獙憇ql語句捧弃。代碼小編也已經(jīng)上傳到Github,項目名稱YIIFMDB,也已經(jīng)支持Cocoapods擦囊,如果您喜歡违霞,請別吝嗇你手里的star。)