J'ai deux classes. Classe A
a la classe B
, mais la classe B
ne connaît pas l'existence de la classe A
KVO infinit loop avec liaison bidirectionnelle
Les deux classes peuvent être modifiés par des facteurs externes (tels que les services ou la logique)
Mais je dois garder les deux classes synchronisées avec la même valeur
Comme classe A
connaît la classe B
, je peux faire une affectation directe après sa valeur est modifiée
Pour la classe B
connaître la classe A
, j'ai décidé de mettre en œuvre KVO, de cette façon la classe A
est averti lorsque la classe B
change
Mon code ressemble à ceci
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?
}
Le problème est que mon code reste en boucle infinie
Parce que chaque fois que ma classe B
est modifiée, elle notifie la classe A
, et quand la classe A
est mise à jour, elle change à nouveau la valeur de la classe B
qui crée une nouvelle notification et ainsi de suite ...
J'ai déjà essayé d'analyser le Thread.callStackSymbols
pour détecter le cycle et l'arrêter mais sans succès.
Est-ce que votre code réel faire plus? Pour le code que vous avez posté, il n'y a pas de raison pour que la classe A observe la classe B. Tout ce que vous faites dans la classe A quand 'b.someString' est changé, c'est mettre à jour' b.someString' avec la même valeur. Il n'y a aucune raison pour ça. – rmaddy
Bien sûr, vous pouvez ajouter une vérification si l'ancienne et la nouvelle valeur sont les mêmes. Si elles sont identiques, ne faites rien. – rmaddy
@maddy - J'ai pensé à vérifier les anciennes et les nouvelles valeurs. Mais ceci est dans une application très complexe et dans des cas spécifiques ne fonctionne pas, et il est nécessaire de créer des solutions alternatives pour ces cas – Pedro