如何封裝一個自動歸、解檔類

WzxJiang發表於2016-05-17

前言

移動端的資料持久化儲存方法有很多種:fmdb、coredata、realm(很強大)、archive(歸檔)等等… 眾所周知,sql系列只能儲存基本資料型別,不支援直接儲存Object物件型別。realm雖然支援儲存Object物件,但是對於已經在使用sql系列的專案來說替換成本還是挺高的。

所以我覺得當你使用sql型別來儲存資料但是又想儲存少量的Object物件,或者App僅僅需要少量的資料儲存的時候是完全可以使用歸檔來滿足你的需求的。

所以我封裝了WZXArchiver來幫我無腦歸、解檔。順便分享我是怎麼封裝的,如果你有更好的做法或者意見歡迎評論!

WZXArchiver 已實現功能:
1. 基本資料的自動歸、解檔。
2. 包含物件的物件的自動歸、解檔(解檔有點不完美)。
3. 清除所有的歸檔。(這裡不講)

正文

要封裝一個自動歸檔、解檔類,首先我們知道歸檔的基本使用.

歸檔的基本使用

建立一個NSObject物件: ManModel,它有兩個成員變數NSString型別的name、NSInteger型別的age。

在.m中實現的協議方法(**所有原生的類都是實現了NSCoding協議的,所以你不用在@interface ManModel : NSObject後面加上**)

然後就可以開始歸檔了:


如何封裝一個自動歸檔、解檔類

首先肯定是建立一個NSObject的類別

為什麼用類別又不是建立一個工具類?
1. 因為用類別可以少很多引數。
2. 可以重寫的協議方法來實現自動歸、解檔。

新增方法

這裡一定要傳入一個算是識別符號的字串,因為我歸檔的時候要以它為檔名WZX_類名_識別符號.archiver,解檔的時候再根據這個字串去解檔。

獲取物件的成員變數

要實現自動xxx,基本上是要用到runtime的,這裡也不例外。
不過這裡有一點要注意一下:我把獲取物件成員變數的方法單獨放在一個類別裡,提高複用性

獲取物件的成員變數的流程:
1. 建立類別#import "NSObject+WZXProperties.h"
2. 匯入標頭檔案 #import
3. 獲取成員變數

這裡可以看到,我返回的是一個字典陣列,每個字典包含name(變數名)和type(變數型別)。變數型別肯定是要根據attributes來判斷的:

裡面有一個__Model__:,用來判斷包含的自定義成員變數,傳回"__Model__:自定義成員變數的類名"


自動化歸檔

重寫encodeWithCoder:方法

這裡基本就是判斷型別來分別編碼,就幾個點要說一下:
1. 通過[self valueForKey:xxx]可以取出self的成員變數對應的值。
2. 通過是否以__Model__ :開頭來判斷是不是自定義的物件,若是自定義的物件再通過wzx_archiveToName: andIsSon:來將包含的子物件歸檔,子物件歸檔的地址是這樣的:WZX_物件類名_物件定義的識別符號_子物件類名_子物件名.archiver
仔細想想,這裡物件定義的識別符號其實我們是得不到的,因為這是在協議的方法裡面,無法直接傳遞name到這個方法中,所以我們要給這個類別新增一個成員變數。

給類別新增成員變數

首先若你希望物件能獲取這個成員變數,你可以直接在.h中新增一個成員變數。 否則你需要在.m中新增:

然後重寫set、get方法,在類別中新增成員變數還是得用到runtime。

這樣我們就成功給類別新增了一個成員變數。

然後我們在wzx_archiveToName:方法時,self.WZX_Archiver_Name = name; 你就會發現還有一個問題,物件包含的子物件歸檔時也會走這個方法,這樣的話 self.WZX_Archiver_Name會被更改,從而導致子物件歸檔的檔名不對。 所以我們必須要做判斷:

子類就走wzx_archiveToName:path andIsSon:YES方法。

這樣自動化歸檔部分就完成了。


自動化解檔

重寫initWithCoder方法

這裡先消除在類別中重寫init方法的警告. 然後因為NSObject是基類不能使用super,所以這裡沒用self = [super initWithCoder:aDecoder],但是我覺得是沒有影響的,NSObject類肯定不會使用XIB或者故事版,所以自然不會使用這個方法,那麼就不會有什麼影響。

解編碼

大致和編碼一致,根據型別分別編碼。 這裡有一點沒處理好:這裡我將對子物件的解檔註釋了,因為我在解檔的方法中對self. WZX_Archiver_Name 賦了值,而在解編碼的時候取回來的時候卻為nil。所以現在只能通過這個方法來解檔:

如果你有更好的處理方法歡迎評論!

現在自動化解檔就可以了。


使用效果:

PS.

更多的細節可以看原始碼

原始碼地址 如果你喜歡這個專案,歡迎 star

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

如何封裝一個自動歸、解檔類 如何封裝一個自動歸、解檔類

相關文章