swift_观察者模式

观察者模式 在iOS开发中应用相当广泛,即:Key-Value Observing,它提供一种机制,当指定的对象的属性(相应的keyPath)被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者。

swift中使用KVO要比OC中稍显局限:

  • NSObject的子类:观察者和被观察者都必须是 NSObject 的子类。 因为OC中KVO的实现基于 KVC 和 runtime 机制,只有是 NSObject 的子类才能利用这些特性。
  • @dynamic:观察的自定义类的属性需要使用 @dynamic 关键字修饰。

以上这两个条件,就使得以往OC中的使用KVO来观察某个枚举属性的type的变化,在swift中就行不通,当然还包括了swift中的结构体以及泛型。

下面来看下swift中实现kvo
自定义类
import UIKit

class FLObbserve: NSObject {
    dynamic var name:String? //dynamic 修饰属性 表示该属性的存取都由 runtime 在运行时来决定
    override init() {
        name = "123"
        super.init()
        
        addObserver(self, forKeyPath: "name", options: .new, context: nil)
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        print("kvo is valid")
    }
    
    deinit {
        removeObserver(self, forKeyPath: "name")
    }
}

运行后,外部修改name属性,控制台打印结果:
kvo is valid

由此在实现了上述两个条件后,为自定义类添加了kvo。


那么对于Struct,Enum这些值类型的如何实现观察者模式呢?
这边我们就要引入一个属性观察器的概念:
Swift 中可以为一个属性设置属性观察器,可以说是内建的 KVO 观察,只不过只限于对自身属性的观察。
看下代码:

//MARK: 设置自定义属性的属性观察器
    var direction:Direction {
        willSet{ // direction属性变化前要执行事件
        }
        didSet { // direction属性变化后要执行事件
            changeDirection(direction: direction)
        }
    }

其中,Direction是自定义的枚举
属性观察器只在在初始化完成后触发,而且不限于 NSObject 的子类,Swift 中所有的 Class, Struct, Enum 都可以使用。
其中,Array, Dictionary, Set 等值类型,对其内容的修改(增/删/替换)元素也会触发属性观察器。因为Array、Dictionary、Set 等值类型更改内容后,会将新的内容复制到变量,变量的地址也发现变化。

你可能感兴趣的:(swift_观察者模式)