Swift class和struct的解歸檔

NSCoding

這種方式是OC中就有的,比較老的方式,并且使用限制是只能是calss,然后實現(xiàn)NSCoding,對于struct是不能使用的。

internal func encode(with aCoder: NSCoder) {
        var count :UInt32 = 0
        if let ivar = class_copyIvarList(self.classForCoder, &count) {
            for i in 0..<Int(count) {
                let iv = ivar[i]
                //獲取成員變量的名稱 -> c語言字符串
                if let cName = ivar_getName(iv) {
                    //轉(zhuǎn)換成String字符串
                    guard let strName = String(cString: cName, encoding: String.Encoding.utf8) else{
                        //繼續(xù)下一次遍歷
                        continue
                    }
                    //利用kvc 取值
                    let value = self.value(forKey: strName)
                    aCoder.encode(value, forKey: strName)
                }
            }
            // 釋放c 語言對象
            free(ivar)
        }
    }
    
    internal required init?(coder aDecoder: NSCoder) {
        super.init()
        var count :UInt32 = 0
        if let ivar = class_copyIvarList(self.classForCoder, &count) {
            for i in 0..<Int(count) {
                let iv = ivar[i]
                //獲取成員變量的名稱 -》 c語言字符串
                if let cName = ivar_getName(iv) {
                    //轉(zhuǎn)換成String字符串
                    guard let strName = String(cString: cName, encoding: String.Encoding.utf8) else{
                        //繼續(xù)下一次遍歷
                        continue
                    }
                    //進行解檔取值
                    let value = aDecoder.decodeObject(forKey: strName)
                    //利用kvc給屬性賦值
                    setValue(value, forKeyPath: strName)
                }
            }
            // 釋放c 語言對象
            free(ivar)
        }
    }

利用運行時設(shè)置好屬性,這樣又多了一層限制,必須繼承NSObject,因為運行時只有繼承NSObject才會具備。如果不介意手動一行一行設(shè)置屬性,那大可不繼承NSObject。

static func saveCustomObject(customObject object: NSCoding, key: String) {
        let encodedObject = NSKeyedArchiver.archivedData(withRootObject: object)
        self.userDefaults.set(encodedObject, forKey: key)
        self.userDefaults.synchronize()
    }
    
    static func removeCustomObject(key: String) {
        self.userDefaults.removeObject(forKey: key)
    }
    
    static func getCustomObject(forKey key: String) -> Any? {
        if let decodedObject = self.userDefaults.object(forKey: key), let data = decodedObject as? Data {
            let object = NSKeyedUnarchiver.unarchiveObject(with: data)
            return object
        }
        return nil
    }

這樣就把class歸檔,解檔做好了,對于struct的歸檔必須使用取巧的方式參考這里或者這里面,NSCoding只適用于class,系統(tǒng)并沒有提供專門的針對struct的解歸檔的協(xié)議.

Swift4.0后Codable

Swift4.0后解歸檔就變得容易多了Codable,這個協(xié)議對于class或是struct都適用,并且使用起來很簡單方便。

class ClassA: Codable {
    private var message : String? = "message"
    private var nu : String? = "nu"
    private var condition : String? = "condition"
    var com : String? = "com"
    var status : String? = "status"
    var state : String? = "state"
    var data : [ClassB]? = []
}

struct ClassB: Codable{
    var time : String? = "time"
    var ftime : String? = "ftime"
    var context : String? = "context"
    var location : String? = "location"
}

定義class和struct,只要聲明實現(xiàn)Codable協(xié)議,不需要做額外的其他操作,比如不需要手動添加設(shè)置解歸檔的key等等。系統(tǒng)都會幫你搞定。不過需要注意的是Codable并不支持繼承方式的子類解歸檔,也就是如果ClassC繼承ClassA,如果對ClassC解歸檔時不會成功的,也就是說Codable不能夠被繼承使用,所以只能在子類實現(xiàn)Codable,父類不去實現(xiàn)Codable。

let a = ClassA()
        let b = ClassB()
        a.data = [b]
        //歸檔
        let encoder = JSONEncoder()
        if let data = try? encoder.encode(a) {
            print(String(data: data, encoding: .utf8)!)
            UserDefaults.standard.set(data, forKey: "piaojin")
        }
        
        let object = UserDefaults.standard.object(forKey: "piaojin")
        //解檔
        let decoder = JSONDecoder()
        if let data = object as? Data {
            let objectA = try? decoder.decode(ClassA.self, from: data)
            print("\(String(describing: objectA))")
        }

這樣就搞定了,關(guān)于Codable的詳細介紹可以參考這里這里。

最后編輯于
?著作權(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)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,098評論 0 9
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,656評論 30 472
  • Swift2.0 1.defer譯為延緩、推遲之意類似棧 注意作用域,其次是調(diào)用順序——即一個作用域結(jié)束(注意),...
    zeqinjie閱讀 3,518評論 0 50
  • 如今,誰要是沒聽說過互聯(lián)網(wǎng)+,肯定會死在今天的晚上。 行業(yè)描述 2014年我國經(jīng)常參加體育鍛煉的人數(shù)達到4.1億,...
    劉明學(xué)閱讀 643評論 0 1
  • 無戒365極限挑戰(zhàn)日更營第4天 文:木子羅 這些日子,天頂漸漸的高了,云也漸漸的淡了,連天空的藍色也透亮了,變成一...
    木子羅閱讀 780評論 18 34

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