Swift中KVO的使用

注:文章参考链接https://www.cnblogs.com/luobenpaidui/p/9354410.html,在此表示感谢。。。

在swift4.0 中 KVO 出现了变更,添加了监听回调.变得更加简单易用.同时会自动释放.不用再remove了.但是相对于OC中使用来说还是有一些需要注意的地方:

  1. 被监听的类需要用 @objcMembers 修饰,否则无法触发
  2. 你需要监听哪个属性,则该属性需要用dynamic 修饰,否则不会触发回调

实现方式一

@objcMembers class MyNumber: NSObject {
    dynamic var value : Int = 1
}

class ViewController: UIViewController {
    
    var testNum : MyNumber!

    override func viewDidLoad() {
        super.viewDidLoad()

        testNum = MyNumber.init()
        testNum.addObserver(self, forKeyPath: "value", options: [.new, .old], context: nil)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        testNum.value += testNum.value
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
   
        if let old = change?[.oldKey] {
            print(old)
        }
                
        if let new = change?[.newKey] {
            print(new)
        }
    }

    deinit {
        testNum.removeObserver(self, forKeyPath: "value", context: nil)
    }
}

实现方式二

@objcMembers class MyNumber: NSObject {
    dynamic var value : Int = 1
}

class ViewController: UIViewController {
    
    var testNum : MyNumber!

    //需要添加一个属性来持有NSKeyValueObservation 否则在函数执行完毕后将会被释放
    var observer : NSKeyValueObservation?

    override func viewDidLoad() {
        super.viewDidLoad()

        testNum = MyNumber.init()
        observer = testNum.observe(\MyNumber.value, options: [.old, .new]) { (model, change) in
                        
            if let old = change.oldValue {
                print(old)
            }
            
            if let new = change.newValue {
                print(new)
            }
        }
        
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        testNum.value += testNum.value
    }

    deinit {
        testNum.removeObserver(self, forKeyPath: "value", context: nil)
    }
}

实现方式三——使用RxSwift

@objcMembers class MyNumber: NSObject {
    dynamic var value : Int = 1
}

class ViewController: UIViewController {

    var testNum : MyNumber!
    var observer : NSKeyValueObservation?
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        testNum = MyNumber.init()
        testNum.rx.observeWeakly(Int.self, "value")
            .subscribe(onNext: { (value) in
                print(value as Any)
                
            }).disposed(by: disposeBag)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        testNum.value += testNum.value
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • KVO底层原理[https://www.jianshu.com/p/e59bb8f59302]NSObject基类...
    90后的晨仔阅读 1,118评论 0 2
  • SWIFT4.0中的KVO 在swift4.0 中 KVO 出现了变更,添加了监听回调.变得更加简单易用.同时会自...
    小旗_96e8阅读 622评论 0 0
  • 上半年有段时间做了一个项目,项目中聊天界面用到了音频播放,涉及到进度条,当时做android时候处理的不太好,由于...
    DaZenD阅读 3,047评论 0 26
  • 简介 KVO(键值监听),即 Key-Value Observing, 是Objective-C 对观察者设计模式...
    Arthur澪阅读 288评论 0 0
  • 第一节 《The Swift Programming Language》 http://numbbbbb.gitb...
    恒筠阅读 1,357评论 0 2