天天看點

iOS資料持久化之二——歸檔與設計可存儲化的資料模型基類(一)iOS資料持久化之二——歸檔與設計可存儲化的資料模型基類

iOS資料持久化之二——歸檔與設計可存儲化的資料模型基類

一、引言

       在上一篇部落格中,我們介紹了用plist檔案進行資料持久化的方法。雖然簡單易用,但随着開發的深入,你會發現,這種方式還是有很大的局限性。試想,如果我們可以将使用者的登入傳回資訊模型,遊戲中角色的屬性資訊模型進行直接的持久化存取,那是不是非常爽的事,幸運的是,我們可以通過歸檔,來設計一個這樣的資料模型。

二、先來精通歸檔吧

       歸檔也是iOS提供給開發者的一種資料存儲的方式,事實上,幾乎所有的資料類型都可以通過歸檔來進行存取。其存儲與讀取的過程,主要封裝在兩個類中:NSKeyedArchiver和NSKeyedUnarchiver。

1、歸檔的原理

       歸檔是将一種或者多種資料類型進行序列化,解歸檔的過程就是将序列化的資料進行反序列化的解碼,這裡需要注意一點,歸檔的核心并非是資料的持久化處理,而是資料的序列化處理,持久化的處理依然是通過檔案存取來實作的。是以,被歸檔的資料類型都必須遵守一個相同的協定,才能在這個協定的限制下進行正确的歸檔與解歸檔,這個協定就是NSCoding協定,我們可以先來看一下NSCoding中的内容:

@protocol NSCoding

- (void)encodeWithCoder:(NSCoder *)aCoder;

- (id)initWithCoder:(NSCoder *)aDecoder;

@end

這個協定非常簡單,一個init的歸檔方法,一個encode的解歸檔方法,NSCoder就是歸檔對象。原則上說,無論是什麼資料類型的對象,系統的或者是我們自定義的,都可以通過實作這個協定中的方法來支援歸檔操作。

2、幾種歸檔與解歸檔的應用

(1)通過類方法來對rootKey進行歸檔

       這種方式,我個人了解,很類似于NSUserDefaults中的standardUserDefaults,隻是後者是系統為我們建立的一個預設plist檔案,而rootKey是系統為我們建立的一個預設的歸檔鍵值。說起來比較複雜,舉個例子就十厘清晰了:

   NSString *homeDictionary = NSHomeDirectory();//擷取根目錄

   NSString *homePath  = [homeDictionary stringByAppendingPathComponent:@"atany.archiver"];//添加儲存的檔案名

   //方式一:通過data資料歸檔,在将資料寫入檔案

   NSData *data= [NSKeyedArchiver archivedDataWithRootObject:@"123"];

   [data writeToFile:homePath atomically:YES];

   //方式二:直接寫入檔案

   [NSKeyedArchiver archiveRootObject:@"456" toFile:homePath];

   //方式一和方式二的效果完全一樣 隻是解歸檔的時候不同

   //方式一的解歸檔:先擷取data資料,在進行data資料的解歸檔

   NSLog(@"%@",[NSKeyedUnarchiver unarchiveObjectWithData:data]);

   //方式二的解歸檔:直接解檔案中的歸檔

   NSLog(@"%@",[NSKeyedUnarchiver unarchiveObjectWithFile:homePath]);

上面的示例是對字元串類型進行的歸檔,是對單一的資料對象進行的歸檔,當然,這裡的對象是支援數組、字典等集合的,但集合其中的對象,也必須全部支援歸檔操作。

(2)通過構造新的archiver對象,對多個對象進行歸檔

       除了上面的類方法,我們還可以自己構造一個歸檔對象,來對多種不同的對象進行歸檔:

   //這裡建立一個可變的data對象作為歸檔的容器

   NSMutableData * data = [[NSMutableData alloc]init];

   //建立一個歸檔對象,歸檔後寫入data資料

   NSKeyedArchiver * archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];

   //對下面的字元串和int值進行歸檔序列化

   [archiver encodeObject:@"jaki" forKey:@"name"];

   [archiver encodeInt:24 forKey:@"age"];

   //寫入data

   [archiver finishEncoding];

   //寫入檔案

   //建立解歸檔的反序列化對象

   NSKeyedUnarchiver * unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];

   //進行反序列化

   NSString * name = [unarchiver decodeObjectForKey:@"name"];

   int age = [unarchiver decodeIntForKey:@"age"];

   //列印資訊

   NSLog(@"\nname:%@\nage:%d",name,age);

結果如下:

iOS資料持久化之二——歸檔與設計可存儲化的資料模型基類(一)iOS資料持久化之二——歸檔與設計可存儲化的資料模型基類