KVC 字典转模型构造函数

作者: MarkusFeng | 来源:发表于2015-12-17 15:01 被阅读524次

    swift /// `重写`构造函数 /// /// - parameter dict: 字典 /// /// - returns: Person 对象 init(dict: [String: AnyObject]) { setValuesForKeysWithDictionary(dict) }

    以上代码编译就会报错!

    原因:

    KVC 是 OC 特有的,KVC 本质上是在运行时,动态向对象发送 setValue:ForKey: 方法,为对象的属性设置数值

    因此,在使用 KVC 方法之前,需要确保对象已经被正确实例化

    添加 super.init() 同样会报错

    原因:

    必选属性必须在调用父类构造函数之前完成初始化分配工作

    讲必选参数修改为可选参数,调整后的代码如下:

    ```swift /// 个人模型 class Person: NSObject {

    /// 姓名

    var name: String?

    /// 年龄

    var age: Int?

    /// `重写`构造函数

    ///

    /// - parameter dict: 字典

    ///

    /// - returns: Person 对象

    init(dict: [String: AnyObject]) {

    super.init()

    setValuesForKeysWithDictionary(dict)

    }

    } ```

    运行测试,仍然会报错

    错误信息:this class is not key value coding-compliant for the key age. -> 这个类的键值 age 与 键值编码不兼容

    原因:

    在 Swift 中,如果属性是可选的,在初始化时,不会为该属性分配空间

    而 OC 中基本数据类型就是保存一个数值,不存在可选的概念

    解决办法:给基本数据类型设置初始值

    修改后的代码如下:

    ```swift /// 姓名 var name: String? /// 年龄 var age: Int? = 0

    /// 重写构造函数 /// /// - parameter dict: 字典 /// /// - returns: Person 对象 init(dict: [String: AnyObject]) { super.init()

    setValuesForKeysWithDictionary(dict)

    } ```

    提示:在定义类时,基本数据类型属性一定要设置初始值,否则无法正常使用 KVC 设置数值

    KVC 函数调用顺序

    ```swift init(dict: [String: AnyObject]) { super.init()

    setValuesForKeysWithDictionary(dict)

    }

    override func setValue(value: AnyObject?, forKey key: String) { print("Key (key) (value)")

    super.setValue(value, forKey: key)

    }

    // NSObject 默认在发现没有定义的键值时,会抛出 NSUndefinedKeyException 异常 override func setValue(value: AnyObject?, forUndefinedKey key: String) { print("UndefinedKey (key) (value)") } ```

    setValuesForKeysWithDictionary 会按照字典中的 key 重复调用 setValue:forKey 函数

    如果没有实现 forUndefinedKey 函数,程序会直接崩溃

    NSObject 默认在发现没有定义的键值时,会抛出 NSUndefinedKeyException 异常

    如果实现了 forUndefinedKey,会保证 setValuesForKeysWithDictionary 继续遍历后续的 key

    如果父类实现了 forUndefinedKey,子类可以不必再实现此函数

    子类的 KVC 函数

    ```swift /// 学生类 class Student: Person {

    /// 学号

    var no: String?

    } ```

    如果父类中已经实现了父类的相关方法,子类中不用再实现相关方法

    相关文章

      网友评论

        本文标题:KVC 字典转模型构造函数

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