NSKeyedArchiver簡述

???? 最近我們可愛的測試工程師向我提出了一個關(guān)于用戶登錄狀態(tài)存儲的問題从隆,仔細(xì)看了下代碼古毛,正好整理了下NSKeyedArchiver的使用問題,所以形成了這些文字实牡,也是我在簡書的第一篇文章斋荞!

1.1關(guān)于數(shù)據(jù)的持久化存儲的幾種方式

??? 說到NSKeyedArchiver,也就先要了解下iOS開發(fā)中關(guān)于數(shù)據(jù)持久化存儲的幾種方式:1.屬性列表 2.對象歸檔 3.數(shù)據(jù)庫存儲(SQLite) 4.Apple提供的CoreData存儲工具荞雏,關(guān)于以上存儲方式的使用場景和各自的優(yōu)缺點,我在此就不再贅述了,今天主要談一談關(guān)于第二類存儲方式-對象歸檔的使用方法和特點凤优。

1.2什么是對象歸檔

歸檔是一種很常用的文件儲存方法悦陋,幾乎任何類型的對象都能夠被歸檔儲存(實際上是一種文件保存的形式)。

蘋果提供了NSKeyedArchiver和NSKeyedUnarchiver兩個類以供我們把對象序列化和反序列化筑辨,在存儲之前使用NSKeyedArchiver進(jìn)行序列化操作俺驶,并且寫入本地文件,在使用之前使用NSKeyedUnarchiver進(jìn)行反序列化的操作棍辕,以供提取使用暮现!

1.3什么場景下會使用到對象歸檔

在實際的開發(fā)過程中,我們會使用各種數(shù)據(jù)存儲的方式楚昭。

如果是簡單的進(jìn)行一些系統(tǒng)提供的類型栖袋,例如NSArray,NSDictionary,NSString,BOOL,NSInteger,NSfloat等基本數(shù)據(jù)類型或者對象,我們可以選擇系統(tǒng)提供的NSUserDefault這個單例抚太,使用簡單方便塘幅,但是僅僅只能對以上這些特定的數(shù)據(jù)格式進(jìn)行存儲,是否有些局限性尿贫?而且屬性屬性列表這種方式又是否安全呢电媳?可能這些這些條件NSUserDefault都無法滿足!

對于一些規(guī)律性的庆亡,量級比較大的數(shù)據(jù)匾乓,又有規(guī)律可循的數(shù)據(jù),我們可以選擇建表或者使用Apple提供的CoreData進(jìn)行持久化的存儲身冀!

那么如果數(shù)據(jù)的量級不是很大钝尸,沒有必要動用數(shù)據(jù)庫或者是CoreData這種大規(guī)模的殺傷性武器的時候括享,而且又對數(shù)據(jù)的安全性和持久性有那么些要求的時候搂根,我們最好去選擇對象序列化這種中等殺傷性工具了!

1.4對象歸檔的使用方法

使用歸檔的方法對系統(tǒng)提供的基本類型和基本對象進(jìn)行歸檔的操作铃辖,在這里不再闡述了剩愧,如果明白了對自定義對象的歸檔和解檔,那么系統(tǒng)的基本數(shù)據(jù)類型和基本對象的歸檔和解檔也就相對很easy了娇斩!

具體的使用方法我就借用目前我正在開發(fā)維護(hù)的代碼進(jìn)行以下說明:

目前我們產(chǎn)品的需求是在用戶登錄之后仁卷,就持久化存儲用戶的登陸相關(guān)信息,在后續(xù)使用中不需要再次登陸犬第。當(dāng)用戶沒有退出登錄锦积,卸載程序后,重新從App Store中現(xiàn)在app后歉嗓,同樣保持登陸狀態(tài)丰介。

如果僅僅是登陸之后的登陸狀態(tài),使用NSUserDefault完全可以實現(xiàn),只是安全性不是太好而已哮幢,但是當(dāng)用戶在登陸狀態(tài)卸載并且重新安裝app后,仍然要保持登陸狀態(tài)的話,那這個問題就值得思考下了鬼佣!

基于以上需求迅腔,也就是說我們要把用戶的登陸信息存儲在一個地方,這個地方要滿足的條件是1.持久化存儲柜某,用戶登錄后嗽元,再次打開app不需要重新進(jìn)行登錄????? 2.用戶在登錄的狀態(tài)下卸載app,再次重新安裝后喂击,仍然保持卸載前的登陸狀態(tài)还棱,也就是要完美重現(xiàn)卸載前的狀態(tài)!

基于以上的條件惭等,我們自然而然地聯(lián)想到蘋果的sandBox機(jī)制珍手,關(guān)于蘋果的sandBox機(jī)制,我們不再詳述辞做,最關(guān)鍵的一點是:在sandBox中的Document目錄下存儲的文件琳要,會根據(jù)用戶的appleID同步到apple的服務(wù)端,也就是說如果再次安裝app的時候秤茅,此app中的沙盒(sandBox)的Document目錄下的文件會被再次還原(用戶的app購買信息是和用戶的appleID綁定的)稚补,那么需求就被完美的滿足了,具體的代碼實現(xiàn)以及注意事項請繼續(xù)向下閱讀:

@interface IHomeSession : NSObject<NSCoding>

@property (nonatomic, strong) NSString *sessionId;? ? ? ? ????? //會話Id

@property (nonatomic, strong) NSDate? *lastSessionDate;? ? //記錄上一次請求時間

@property (nonatomic, strong) NSString *token;? ? ? ? ? ? ?????? //ut值

@property (nonatomic, strong) NSString *alias;? ? ? ? ? ? ??????? //設(shè)備別名

@property (nonatomic, strong) NSString *username;? ? ? ? ?? //用戶名

//序列化對象的單例

+ (IHomeSession *)sharedMemory;

//保存

- (void)save;

//獲取ssesionId

- (NSString *)getSessionId;

//重置

- (void)reset;

@end


以上是.h文件

具體屬性可以根據(jù)自己的需求進(jìn)行添加

提供獲取序列化單例的方法框喳,方便在項目全局進(jìn)行獲取和使用

提供保存(save),重置(reset)课幕,獲取sessionId(getSessionId)的api接口以供使用,也可以根據(jù)自己的需求添加api

最重要的一點五垮,是當(dāng)前類需要遵循NSCoding協(xié)議乍惊,NSCoding協(xié)議中有兩個方法,都是requred方法放仗,遵循該協(xié)議后润绎,必須實現(xiàn)。

以下是.m文件中NSCoding協(xié)議的具體實現(xiàn)

#pragma mark - NSCoding

- (void)encodeWithCoder:(NSCoder *)aCoder

{

[aCoder encodeObject:_sessionId forKey:@"_sessionId"];

[aCoder encodeObject:_lastSessionDate forKey:@"_lastSessionDate"];

[aCoder encodeObject:_token forKey:@"_token"];

[aCoder encodeObject:_username forKey:@"_username"];

[aCoder encodeObject:_alias forKey:@"_alias"];

}

通過以上編碼的方法诞挨,對當(dāng)前類中的屬性進(jìn)行逐一的鍵值編碼莉撇!

- (id)initWithCoder:(NSCoder *)aDecoder

{

if (self = [super init])

{

_sessionId = [aDecoder decodeObjectForKey:@"_sessionId"];

_alias = [aDecoder decodeObjectForKey:@"_alias"];

_lastSessionDate = [aDecoder decodeObjectForKey:@"_lastSessionDate"];

_token = [aDecoder decodeObjectForKey:@"_token"];

_username = [aDecoder decodeObjectForKey:@"_username"];

}

return self;

}

通過以上解碼的方法,對當(dāng)前類中的屬性惶傻,根據(jù)鍵進(jìn)行逐一的逆向編碼棍郎,并返回一個當(dāng)前類的實例!


實現(xiàn)了以上的協(xié)議方法后银室,我們就可對當(dāng)前的類對象進(jìn)行歸檔和解檔的操作了:

首先我們規(guī)定一個歸檔文件在沙盒中的存儲路徑涂佃,寫在一個類方法中静秆,方便取用,為了滿足app重新安裝后仍然可以獲取到最后一次登陸信息的需求巡李,我們把文件存儲在沙盒中的第一個文件夾(Document)中抚笔,這樣可以在程序重新安裝后自動回復(fù),原理我在需求分析上已經(jīng)做了闡述侨拦!

+ (NSString *)path

{

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentDir = [paths objectAtIndex:0];

NSString *dstPath = [documentDir stringByAppendingPathComponent:@"user.data"];

return dstPath;

}

歸檔的方法殊橙,我們集成在save的接口中:

- (void)save

{

[NSKeyedArchiver archiveRootObject:self toFile:[IHomeSession path]];

}

解檔的方法我們集成在單例的獲取中,一定要先查找對應(yīng)路徑下的文件是否存在狱从,如果存在進(jìn)行解檔操作膨蛮,不存在的話重新生成一個單例,這樣會增強(qiáng)程序的健壯性季研,防止誤取單例敞葛,造成程序崩潰!

+ (IHomeSession *)sharedMemory

{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

if ([[NSFileManager defaultManager] fileExistsAtPath:[IHomeSession path]]) {

instance = [NSKeyedUnarchiver unarchiveObjectWithData:

[NSData dataWithContentsOfFile:[IHomeSession path]]];

}

else

{

instance = [[IHomeSession alloc] init];

}

});

return instance;

}

重置的接口中与涡,我們需要刪除本地文件惹谐,同時將單例中的各種屬性恢復(fù)到初始狀態(tài),然后將初始狀態(tài)下的對象保存歸檔驼卖!

- (void)reset

{

[[NSFileManager defaultManager] removeItemAtPath:[IHomeSession path] error:nil];

instance = [[IHomeSession alloc] init];

instance.sessionId = nil;

instance.lastSessionDate = nil;

instance.token = @"default";

instance.username = nil;

instance.alias = nil;

[instance save];

}


OK了氨肌,以上的關(guān)鍵代碼實現(xiàn)之后,歸檔和解檔的操作就可以完美實現(xiàn)了酌畜,在程序的任何一個地方都可以依托IHomeSeesion這個單例完成操作了怎囚,至于后續(xù)需要存儲的字段,可以根據(jù)產(chǎn)品需求依次添加了桥胞!

以上代碼的形成如有不夠嚴(yán)謹(jǐn)?shù)牡胤娇沂兀瑲g迎指出!謝謝贩虾!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末催烘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子整胃,更是在濱河造成了極大的恐慌颗圣,老刑警劉巖喳钟,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屁使,死亡現(xiàn)場離奇詭異,居然都是意外死亡奔则,警方通過查閱死者的電腦和手機(jī)蛮寂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來易茬,“玉大人酬蹋,你說我怎么就攤上這事及老。” “怎么了范抓?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵骄恶,是天一觀的道長。 經(jīng)常有香客問我匕垫,道長僧鲁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任象泵,我火速辦了婚禮寞秃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘偶惠。我一直安慰自己春寿,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布忽孽。 她就那樣靜靜地躺著绑改,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兄一。 梳的紋絲不亂的頭發(fā)上绢淀,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音瘾腰,去河邊找鬼皆的。 笑死,一個胖子當(dāng)著我的面吹牛蹋盆,可吹牛的內(nèi)容都是我干的费薄。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼栖雾,長吁一口氣:“原來是場噩夢啊……” “哼楞抡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起析藕,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤召廷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后账胧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體竞慢,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年治泥,在試婚紗的時候發(fā)現(xiàn)自己被綠了筹煮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡居夹,死狀恐怖败潦,靈堂內(nèi)的尸體忽然破棺而出本冲,到底是詐尸還是另有隱情,我是刑警寧澤劫扒,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布檬洞,位于F島的核電站,受9級特大地震影響沟饥,放射性物質(zhì)發(fā)生泄漏疮胖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一闷板、第九天 我趴在偏房一處隱蔽的房頂上張望澎灸。 院中可真熱鬧,春花似錦遮晚、人聲如沸性昭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽糜颠。三九已至,卻和暖如春萧求,著一層夾襖步出監(jiān)牢的瞬間其兴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工夸政, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留元旬,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓守问,卻偏偏與公主長得像匀归,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子耗帕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 27穆端、ViewController的didReceiveMemoryWarning是在什么時候調(diào)用的?默認(rèn)的操作是...
    煙雨平生花飛舞閱讀 563評論 0 1
  • 下面是我最近兩年學(xué)習(xí)OC中的一些基礎(chǔ)知識仿便,對于學(xué)習(xí)OC基礎(chǔ)知識的人可能有些幫助体啰,拿出來分享一下,還是那句話不喜勿噴...
    小小趙紙農(nóng)閱讀 2,562評論 1 7
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉嗽仪,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,679評論 0 9
  • 把 OC 中基本數(shù)據(jù)存儲到沙盒中,被稱為基本數(shù)據(jù)持久化鲤氢。 基本數(shù)據(jù)搀擂,在 oc中有以下四種,分別為 NSString...
    flyrees閱讀 1,122評論 0 0
  • 本文結(jié)構(gòu) 參考孟巖老師的文章卷玉,對本文結(jié)構(gòu)如下劃分 基本數(shù)據(jù)類型基本語法數(shù)組和其他集合類基本輸入輸出和文件處理哨颂,輸入...
    不抄完整本三國不改名閱讀 507評論 0 1