KVO 无限循环,带 2 路绑定



我有两个类。类A有类B,但类B不知道类的存在A

这两个类都可以通过外部因素(如服务或逻辑)进行更改

但是我需要以相同的值保持两个类同步

由于类A知道类B,我可以在其值更改后进行直接赋值

为了让类B知道类A,我决定实现KVO,这样当类B被更改时,类A就会得到通知

。我的代码看起来像这样

class A : NSObject {
var b : B
@objc dynamic var anOtherString:String? {
didSet{
b.someString = self.anOtherString
}
}
override init() {
self.b = B()
super.init()
addObserver(self, forKeyPath: #keyPath(b.someString), options: [.old , .new], context: nil)
}
// MARK: - Key-Value Observing
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == #keyPath(b.someString) {
// Update Time Label
anOtherString = b.someString
}
}
}

class B : NSObject {
@objc dynamic var someString: String?
}

问题是我的代码保持在无限循环中

因为每当我的类B发生变化时,它都会通知类A,当类A更新时,它会再次更改创建新通知的类B的值,依此类推......

我已经尝试分析Thread.callStackSymbols以检测周期并停止它,但没有成功。

由于当 A 因 B 而更改时,您不能允许 A 更新 B,因此您可以使用一个布尔变量来跟踪 A 是否需要更新 B。

class A : NSObject {
var b : B
var bChanged: Bool = false // Logic to track if B made a change
@objc dynamic var anOtherString:String? {
didSet{
// If B did not make a change, then update B
if !bChanged {
b.someString = self.anOtherString
// Otherwise set the flag
}else {
bChanged = false
}
}
}
override init() {
self.b = B()
super.init()
addObserver(self, forKeyPath: #keyPath(b.someString), options: [.old , .new], context: nil)
}
// MARK: - Key-Value Observing
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == #keyPath(b.someString) {
// Update Time Label
bChanged = true // B made a change
anOtherString = b.someString
}
}
}

最新更新