我有两节课。班级A
有班级B
,但班级B
不知道班级A
的存在
这两个类都可以被外部因素(例如服务或逻辑)改变
但是我需要保持两个类与同一个值同步
由于班级A
知道班级B
,我可以在其值更改后进行直接作业
为了让课程B
了解班级A
,我决定实施KVO,这样,当班级A
发生变化时会通知班级B
我的代码看起来像这样
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
以检测周期并停止它但没有成功。
答案 0 :(得分:0)
由于B因A而改变时不能允许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
}
}
}