美文网首页程序员iOS DeveloperiOS技术点
Swift3.0中如何使用RunTime对数据进行归档和反归档

Swift3.0中如何使用RunTime对数据进行归档和反归档

作者: Fluent | 来源:发表于2016-06-06 16:36 被阅读810次

    在开发中我们经常会遇到要把数据保存到本地,在iOS中数据持久化的方法基本上有以下5种:
    1.writeToFile;
    2.NSUserDefults;
    3.NSCoding(归档/反归档);
    4.sqlite;
    5.coreData。
    今天小编主要介绍第三种:
    首先创建一个model继承NSObject,并且遵守NSCoding协议和实现它的两个方法。以下是不使用runtime和使用runtime的对比:

    不使用runtime写法

        // 归档
        func encodeWithCoder(aCoder: NSCoder) {
            aCoder.encodeObject(name, forKey: "name")
            aCoder.encodeObject(age, forKey: "age")
            aCoder.encodeObject(number, forKey: "number")
        }
        // 反归档
        required init?(coder aDecoder: NSCoder) {
            super.init()
            name = aDecoder.decodeObjectForKey("name") as? String
            age = aDecoder.decodeObjectForKey("age") as? Int
            number = aDecoder.decodeObjectForKey("number") as? NSNumber
        }
    

    使用runTime写法

    之前是Swift2.0写的,有一些问题,现在已更新3.0

    直接看代码

    class LCBaseModel: NSObject, NSCoding {
        // 使用runtime属性前面必须加dynamic,并且是不可选类型,意思是允许动态更新属性
        dynamic var name = ""
        dynamic var age = 0
        
        override init() {
            
        }
        
        // 归档
        func encode(with aCoder: NSCoder) {
            var count: UInt32 = 0
            guard let ivars = class_copyIvarList(self.classForCoder, &count) else {
                return
            }
            for i in 0 ..< count {
                let ivar = ivars[Int(i)]
                let name = ivar_getName(ivar)
                
                let key = NSString.init(utf8String: name!) as! String
    
                if let value = self.value(forKey: key) {
                    aCoder.encode(value, forKey: key)
                }
            }
            // 释放ivars
            free(ivars)
        }
    
        // 反归档
        required init?(coder aDecoder: NSCoder) {
            super.init()
            var count: UInt32 = 0
            guard let ivars = class_copyIvarList(self.classForCoder, &count) else {
                return
            }
            for i in 0 ..< count {
                let ivar = ivars[Int(i)]
                let name = ivar_getName(ivar)
                let key = NSString.init(utf8String: name!) as! String
                if let value = aDecoder.decodeObject(forKey: key) {
                    self.setValue(value, forKey: key)
                }
            }
            // 释放ivars
            free(ivars)
        }
        
    }
    

    下面是使用

        override func viewDidLoad() {
            super.viewDidLoad()
            let model = LCBaseModel()
            model.name = "FlyChang"
            model.age = 25
            
            var path = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).last
            path = path! + "/Model"
            let data = NSMutableData()
            let archiver = NSKeyedArchiver.init(forWritingWith: data)
            archiver.encode(model, forKey: "model")
            archiver.finishEncoding()
            data.write(toFile: path!, atomically: true)
            
            let data1 = NSData(contentsOfFile: path!)
            let una = NSKeyedUnarchiver.init(forReadingWith: data1! as Data)
            let m = una.decodeObject(forKey: "model") as! LCBaseModel
            una.finishDecoding()
            print("-----------runtime-----")
            print(m.name)
            print(m.age)
        }
    

    总结:

    1. 在swift中不需要引入runtime文件,系统默认就引入了;
    2. 属性前面加dynamic,并且不可选。

    相关文章

      网友评论

        本文标题:Swift3.0中如何使用RunTime对数据进行归档和反归档

        本文链接:https://www.haomeiwen.com/subject/aozrdttx.html