假设我有一个像这样的简单树状结构:
class Tree {
weak var ancestor: Tree?
var children = [Tree]()
}
树的每个节点都保留对其子节点的引用,以及对最老祖先的弱节点(以避免引用循环)。
每当我在其根上设置子树时,我想自动更新子树所有节点的祖先属性。
let grandParent = Tree()
let parent = Tree()
let child = Tree()
let grandChild = Tree()
child.children.append(grandChild)
parent.children.append(child)
grandParent.children.append(parent)
// Should set ancestor in the whole hierarchy.
grandParent.ancestor = grandParent
我尝试使用属性观察器来实现这一点,只要设置了它的祖先,就在节点的子节点上进行迭代,以便传播该值,但注意到既没有didSet
也没有willSet
被调用传递第一个孩子。这是我一直在使用的代码:
weak var ancestor: Tree? = nil {
didSet {
for child in self.children {
child.ancestor = self.ancestor
}
}
}
正如预期的那样, 的祖先grandParent
被正确设置, 的也是如此parent
。但是,它的后代 (child
和grandChild
) 不是。请注意,我一直在观察相同的结果willSet
(当然调整上面的代码以考虑到self.ancestor
尚未改变的情况)。
有人可以指出我在这里缺少什么吗?
我可以用非常相似的方法对计算属性做我想做的事。但我发现它没有财产观察者那么优雅,如果可能的话,我宁愿避免它。然而,这个片段可以完成任务。
var ancestor: Tree? {
get {
return self._ancestor
}
set(newAncestor) {
self._ancestor = newAncestor
for child in self.children {
child.ancestor = newAncestor
}
}
}
private weak var _ancestor: Tree? = nil