很多时候我们都会把这两个放在一起比较,其实这两个是没有区别的,要说他们最大的区别就是名字可能是一致的,其他的没有任何区别,他们功能也是不一样
简单用法
- KVC
这个是一种键值的赋值操作,最大的作用就是字典转模型
数据的json转model
import UIKit
class UserInfo: NSObject,NSCoding {
var custname : String? = ""
override init() {
super.init()
}
// 从NSObject解析回来
required init(coder aDecoder:NSCoder) {
self.custname = aDecoder.decodeObject(forKey: "custname") as? String
}
func encode(with aCoder: NSCoder) {
aCoder.encode(custname, forKey: "custname")
}
}
使用方法<单个json转model>
guard let dataDict = result as? [String : Any] else {return}
let loginModel = LoginModel(dict: dataDict)
使用方法二<列表json转model>
guard let dataArray = result as? [[String : Any]] else {return}
for dict in dataArray {
let model = SecondModel(dict: dict)
self!.secondModel.append(model)
}
使用方法三
var name : String? {
didSet {//通过oldValue }
willSet {//通过newValue}
}
- KVO
这个是通知的一种形式,根据键对应值的变化来调用方法
使用方法一
//创建观察对象
let button : UIButton = UIButton()
var myContext : NSObject!
myContext = NSObject()
//注册观察者
button.addObserver(self, forKeyPath: "", options: .new, context: &myContext)
//移除观察者
button.removeObserver("", forKeyPath: &myContext)
//获取观察者数据信息
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
}
底层原理
kvc
是在运行时动态的访问和修改对象的属性,它的定义是对NSObjcet的拓展实现
- 当调用setValue:forKey:时 ,程序会先通过setter(set:)方法,对属性进行设置;
- 如果没有找到setKey:方法,KVC机制会检查+
(BOOL)accessInstanceVariablesDirectly方法有没有返回YES
,默认该方法是返回YES的,如果重写返回了NO,那么这一步会执行setValue
forUndefinedKey:方法。若为YES,KVC机制会搜索该类中是否有名为key的成员变量,不管变量在类接口处定义没有,只要存在以key命名的变量,KVC都可以对该成员变量赋值。 - 如果该类既没有setKey方法,也没有_key成员变量,KVC机制会搜索_isKey的成员变量;如果_isKey成员变量也没有,KVC机制再会继续搜索和is的成员变量给它们赋值,如果上面列出的方法或者成员变量都不存在,系统会执行该对象的setValue:forUndefinedKey:方法
抛出异常(既 如果没有找到Set方法的话,会按照_key,_iskey,key,iskey的顺序搜索成员并进行赋值操作)
kvo
KVO的依赖于OC的Runtime来实现的,当观察者对象时,KVO机制动态创建一个对象A的子类(NSKVONotifying_A类),并为这个子类重写了被观察的属性的setter方法,setter方法会负责调用原来的setter方法前后,通知观察对象发生了变化
网友评论