1. 创建 person.swift 对象
class Person: NSObject {
//对象的属性应该是可变的
//可选项,允许变量为空,var 的默认值就是 nil
//在 iOS 开发中,所有的属性是延时加载的
//因为 KVC 是 OC 中的特性,所以要加 @objc 修饰,否则会报错
//super.init 结束后,name 并不会被分配空间
@objc var name: String?
//age 和 KVC 不兼容,OC中 Int 属于基本数据类型,不存在 nil 的概念
//对于基本数据类型,KVC 不会主动调用"构造函数",因此,如果要对基本数据类型,使用KVC设置数值,必须指定初始值,空间已经分配完成
@objc var age: Int = 0
// KVC 的构造函数,用字典设置模型
init(dict: [String: Any]) {
//setValue:forKey 说明:
//1.当给对象发送 setValue:forKey:消息时
//2.会判断属性是否已经被“实例化”
//3.如果没有被实例化 1.调用属性对象的构造函数实例化属性 2.设置数值
//4.如果已经分配了空间,直接设置数值
//设置数值 - 调用 super.init 保证对象已经被创建完成
//KVC 是 OC 特有的,本质是在运行时,动态的给对象发送 'setValue:forKey:' 消息
super.init()
//KVC 的设置数值
setValuesForKeys(dict)
//dict : 会有多个值对 会顺序调用 setValue forKey 给对象的属性设置数值
}
override func setValue(_ value: Any?, forKey key: String) {
print("forKey \(key) \(value)")
//如果对象存在key对应的属性,直接设置数值
//如果对象不存在 key 对应的属性,则调用undefinedKey方法
//undefinedKey方法 默认崩溃 重写没事
super.setValue(value, forKey: key)
}
//默认的 setValueforUndefinedKey 方法 如果出现未定义的key会抛出'NSUndefinedKeyException'异常,让程序崩溃
//如果一旦重写了此方法,同时不 super,不调用父类默认的方法
override func setValue(_ value: Any?, forUndefinedKey key: String) {
print("forUndefinedKey \(key) \(value)")
}
}
2. 调用函数
func demo(){
//po self
let p = Person(dict: ["name": "xiaoxiao", "age": 19, "title": "Test", "no": "007"])
print("\(p.name) \(p.age)")
//print("\(p.name) \(p.age) \(p.no)")
}
3. 子类调用 KVC 构造函数的方式
3.1 创建 Student.swift 文件,并继承 Person.swift
//如果子类没有实现父类的方法,在执行的时,会直接调用父类的方法
class Student: Person {
@objc var no: String?
}
3.2 调用函数
func demo(){
//po self
let p = Student(dict: ["name": "xiaoxiao", "age": 19, "title": "Test", "no": "007"])
//print("\(p.name) \(p.age)")
print("\(p.name) \(p.age) \(p.no)")
}