Chapter 19 Archiving

歸檔有點類似于保存,它是把對象保存成特定的格式,以便以后再用。
歸檔的方法主要有屬性列表和鍵值對編碼。
Archiving with XML Property Lists
MAC OS X應(yīng)用用XML屬性列表來存儲默認(rèn)參數(shù)、應(yīng)用設(shè)定和配置信息。
你可以使用NSString, NSDictionary, NSArray, NSDate, NSData, 或 NSNumber中的writeToFile:atomically:方法把數(shù)據(jù)寫進(jìn)文件。如果你想寫的是dictionary或是array,該方法可以以屬性列的形式寫進(jìn)文件。
writeToFile:atomically:中的atomically經(jīng)常被設(shè)置為YES,這是為了防止在寫入的過程中因遭遇崩潰而導(dǎo)致文件受損。
如果你想用dictionary創(chuàng)建一個屬性列,那么dictionary中的key必須是NSString對象,而值可以是NSString、NSDictionary、NSArray、NSDate、NSData, 或 NSNumber對象。
如果你想從文件中讀一個XML屬性列到程序中,應(yīng)該使用dictionaryWithContentsOfFile:或arrayWithContentsOfFile:。
讀取數(shù)據(jù)的話可以使用dataWithContentsOfFile:。
讀取NSString對象可以使用stringWithContentsOfFile:。
編輯屬性列很隨意,你可以使用文本編輯器,也可以使用OS X中/Developer/Applications/Utilities中的屬性列表編輯程序,NSPropertyListSerialization類允許你以一種機(jī)器便攜式的方式讀寫屬性列從或者到文件。
Archiving with NSKeyedArchiver
使用NSKeyedArchiver類的基于key的存檔可以保存任意類型的對象。
MAC OS X 10.2版本之前的系統(tǒng)只支持連續(xù)歸檔,那是一種讀寫順序嚴(yán)格一致的歸檔方法。
基于key的存檔方法就是為每個對象起一個名字,無論是讀寫都是通過操作這個名字實現(xiàn)的。
這種基于key的存檔方法可以通過NSKeyedArchiver中的archiveRootObject:toFile:方法實現(xiàn),如下圖所示:


通過NSKeyedUnarchiver類中的unarchiveObjectWithFile:方法把數(shù)據(jù)從文件中讀出來,如下圖所示:

Writing Encoding and Decoding Methods
除了上面講的屬性列表,對于歸檔對象,你必須要告訴系統(tǒng)如何歸檔、加密、解檔、解密。
這些是通過把NSCoding協(xié)議中的encodeWithCoder:和initWithCoder:方法添加到類的中定義實現(xiàn)的。
每次把對象歸檔到某文件中encodeWithCoder:方法都會被調(diào)用來加密,至于對應(yīng)的,每次initWithCoder:被調(diào)用來解密。
無論是加解密歸檔對象你都需要指定如何加解密每個對象的實例變量。
在加密方面,對于Objective-C對象而言,你可以使用encodeObject:forKey:,而對于C語言數(shù)據(jù)而言,你可以使用P436中表19.1中的方法。
在解密方面,你可以使用decodeObject:forKey:來解密Objective-C對象,也可以使用表19.1中的方法來解密C語言中的基礎(chǔ)數(shù)據(jù)類型。
如下圖所示:

一般來講類繼承了NSObject的話,你就不用擔(dān)心加密繼承而來的實例變量了。如果你知道父類已經(jīng)實現(xiàn)了NSCoding協(xié)議,那你要確保繼承而來的實例變量也被加密,寫法如下所示:


使用encodeObject:forKey:加密一個對象是給一個對象起一個名字,但是如果你給一個已經(jīng)加密了的對象的子類對象使用相同名字的話可能會引起沖突,所以你在起名字的時候最好把類名放進(jìn)去。
如果你的類想要實現(xiàn)加解密方法,就必須要在@interface中添加NSCoding協(xié)議。

encodeObject:forKey:適用于內(nèi)建類型和實現(xiàn)了NSCoding協(xié)議的類。
UsingNSData to CreateCustom Archives
有的時候你不想把對象直接寫入文件中,可能你想把部分或者全部對象寫入某一單一文件中,你可以使用NSData。
NSData的作用是把內(nèi)存中的一片區(qū)域保存到某一介質(zhì)中。這個介質(zhì)其實是個緩沖區(qū),它要么是把內(nèi)存中數(shù)據(jù)寫進(jìn)硬盤過程中的臨時存儲區(qū)域,要么是從硬盤讀進(jìn)內(nèi)存的過程中的臨時存儲區(qū)域。
一個簡單的開辟這一臨時區(qū)域的方法如下所示,并且它會隨著程序的執(zhí)行而自動的擴(kuò)展。

initForWritingWithMutableData:制定了一塊臨時存儲區(qū)域。
finishEncoding可以終止對對象的加密行為,這個消息也是完成整個歸檔過程的結(jié)尾一步,program19.9演示了整個過程。
[dataArea writeToFile: @"myArchive" atomically: YES]這條語句負(fù)責(zé)把臨時存儲區(qū)域的數(shù)據(jù)寫入某一特定文件。
從文件中恢復(fù)數(shù)據(jù)很簡單。首先,你需要申請一塊空間。然后你需要把文件中的內(nèi)容讀進(jìn)臨時存儲區(qū)。再然后是創(chuàng)建一個NSKeyedUnarchiver對象,解密臨時緩沖區(qū)中的數(shù)據(jù)。結(jié)束的時候你需要發(fā)送一個finishDecoding消息給NSKeyedUnarchiver對象。
Using the Archiver to Copy Objects
你可以使用基礎(chǔ)歸檔機(jī)制實現(xiàn)深層復(fù)制,它的實現(xiàn)原理很簡單。
它把源數(shù)據(jù)歸檔到臨時存儲區(qū),然后再解檔到目標(biāo)數(shù)據(jù)中,因為你歸檔或不歸檔原來的數(shù)據(jù)就在那不變不動。
通過這種深度復(fù)制的方法你甚至可以避免中間賦值過程,一條語句足矣,如下圖所示:

該方法可以支持那種不支持NSCopying協(xié)議的對象。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容