在观察某个属性是否变化的时候,采用 KVO 的方式更为简单直接一些。swift
关于 Swift 的 KVO 使用方法,能够查看王巍的 KVObash
简单来讲,在 Swift 中:框架
@objc dynamic
标签,NSObject
若是不符合则会发生如下异常:ide
sent to an object that is not KVC-compliant for the "***" property.
复制代码
在 RxSwift 框架下,提供了 rx.observe
和 rx.observeWeakly
两种方式的课观察序列。性能
rx.observe 是对 KVO 的简单封装,执行效率更高。它要求被观察的属性路径都是使用 strong 修饰的,若是观察使用 weak 修饰的属性,可会发生崩溃。ui
使用 rx.observe 时,须要注意 循环引用 的问题。若是一个类观察本身的属性,使用 rx.observe 将会产生 循环引用 的问题。spa
rx.observeWeakly 能够处理属性变为空的状况,全部能够用在使用 weak 修饰的属性上。debug
全部能够使用 rx.observe 的地方,都是使用 rx.observeWeakly。可是,rx.observeWeakly 的性能没有 rx.observe 的高。code
下面为采用 RxSwift 框架下的实例:继承
import RxCocoa
import RxSwift
class User: NSObject {
@objc dynamic var name: String
init(name: String) {
self.name = name
}
}
class TestViewController: UIViewController {
@objc dynamic var message = ""
var disposeBag = DisposeBag()
@objc dynamic var user: User = User(name: "fang")
@objc dynamic var number: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .orange
let interval: DispatchTimeInterval = .seconds(1)
Observable<Int>
.interval(interval, scheduler: MainScheduler.instance)
.subscribe(onNext: { [unowned self] (_) in
self.number += 1
self.user.name += "~"
})
.disposed(by: disposeBag)
// 监听 number 属性
self.rx
.observeWeakly(Int.self, "number")
.subscribe(onNext: { (message) in
// 注意: number 为 Int? 类型
debugPrint(message ?? -1)
})
.disposed(by: disposeBag)
// 监听 user.name 属性
self.rx
.observeWeakly(String.self, "user.name")
.subscribe(onNext: { (name) in
// 注意: name 为 Sting? 类型
debugPrint(name ?? "")
})
.disposed(by: disposeBag)
}
}
复制代码
在实例中,观察 user.name
属性时,keypath 中的 user
和 name
属性都要使用 @objc dynamic
进行标记。
也就是说 TestViewController 中的 user 属性须要使用
@objc dynamic
进行标记,User 类中的 name 属性,也要用@objc dynamic
进行标记。
在实例中,必须使用 rx.observeWeakly
进行监听,不然会产生循环应用。
Swift 3 中继承自 NSObject 的类,不须要手动添加 @objc ,编译器会给全部的非 private 的类和成员加上 @objc , private 接口想要暴露给 Objective-C 须要 @objc 的修饰。Swift4 后继承自 NSObject 的类再也不隐式添加 @objc 关键字