花落√莫相思

53-Swift 之 KVO (Key-Value Observ

2017-07-28  本文已影响85人  NetWork小贱

一 、 KVO 的概述

二 、KVO 的使用条件

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)

三 、 KVO 的注册观察者的方法及参数介绍

open func addObserver(_ observer: NSObject, forKeyPath keyPath: String, options: NSKeyValueObservingOptions = [], context: UnsafeMutableRawPointer?)

1、该方法的参数介绍

 

2、NSKeyValueObservingOptions 的取值介绍

四 、 KVO 响应观察者的方法及参数的介绍

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)

该方法的参数介绍

五、 KVO 的注销方法及参数介绍

open func removeObserver(_ observer: NSObject, forKeyPath keyPath: String, context: UnsafeMutableRawPointer?)

或者

open func removeObserver(_ observer: NSObject, forKeyPath keyPath: String)

参数的介绍

六、 KVO 的使用举例

1> 我们首先创建一个 Person 类。

/**
 创建一个类
 */
class Person : NSObject{
    dynamic var name : String?
    var firstName : String?
    var lastName : String?
    /**
     获取用户的名字
     */
    func getPersonName() -> String {
        name = firstName! + lastName!
        return name!
    }
    /**
     反初始化
     */
    deinit {
        print("反初始化完成")
    }
}

2> 注册观察者

/**
 创建一个类
 */
NewPerson = Person.init()
/**
 开始注册观察者
 */
NewPerson.addObserver(self, forKeyPath: "name", options: .new, context: &NewContext)
NewPerson.firstName = "周"
NewPerson.lastName = "NetWork小贱"
/**
 获取名字
 */
let NewName = NewPerson.getPersonName()
MyName = NewName

3> 观察者的响应事件

/**
 观察者方法的实现
 */
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath=="name" {
        print("sss")
        print(object!)
        print(context!)
        print(change!)
    }else{
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
    }
}

4> 当我们观察的类不存在该属性的异常处理

如果Person 类中没有我们要设定的这个属性,则 KVC 也无法找到这个属性值,这时候 KVC 协议其实会调用 valueForUndefinedKey 方法,NSObject 对这个方法的默认实现是抛出一个 NSUndefinedKeyException 异常。

该异常的解决方法

/**
 没有key时的异常处理
 */
override func value(forUndefinedKey key: String) -> Any? {
     return ""
}

则最使用的方法是在观察类中加入上面的方法,则观察类的写法如下:

/**
 创建一个类
 */
class Person : NSObject{
    dynamic var name : String?
    var firstName : String?
    var lastName : String?
    /**
     获取用户的名字
     */
    func getPersonName() -> String {
        name = firstName! + lastName!
        return name!
    }
    
    /**
     没有key时的异常处理
     */
    override func value(forUndefinedKey key: String) -> Any? {
         return ""
    }
    
    /**
     反初始化
     */
    deinit {
        print("反初始化完成")
    }
}

七 、属性观察器的介绍(再次介绍)

1> 介绍

       属性观察器相当于內建的KVO,监控和响应属性值的变化,每次属性被设置值的时候都会调用属性观察器,甚至新的值和现在的值相同的时候也不例外。可以为除了延迟存储属性之外的其他存储属性添加属性观察器,也可以通过重载属性的方式为继承的属性(包括存储属性和计算属性)添加属性观察器。

2> 属性检查其的检测方式

注释
willset观察器会将新的属性值作为固定参数传入,在willSet的实现代码中可以为这个参数指定一个名称,如果不指定则参数仍然可用,这时使用默认名称newValue表示。类似地,didSet观察器会将旧的属性值作为参数传入,可以为该参数命名或者使用默认参数名oldValue。

注意
willSet和didSet观察器在属性初始化过程中不会被调用,它们只会当属性的值在初始化之外的地方被设置时被调用。

3> 举例介绍

/**
 属性观察器
 */
func attributeViewer() -> Void {
    var PersonCount:Int = 0 {
        
        willSet(newValue){
            print("新人数是:" + "\(newValue)" + "个")
        }
        
        didSet(oldValue){
            print("老人数是:" + "\(oldValue)" + "个")
        }
    }
    
    /**
     测试
     */
    
    PersonCount = 10  
}

测试结果图

ACC041EB-F4D8-4EC2-8438-011619B428B5.png
上一篇 下一篇

猜你喜欢

热点阅读