我已经构建了一个树,其树节点如下所示:
class TreeNode {
var isRoot: Bool {
return parentNode == nil
}
var childNodes = [TreeNode]()
weak var parentNode: TreeNode?
private weak var _rootNodeCache: TreeNode?
var rootNode: TreeNode? {
return _rootNodeCache
}
private func updateRootCache(node: TreeNode) {
...// Implementation doesn't matter.
}
}
我想问一下,如果用rootNode
指定计算属性weak
?
没有弱点就可以跑。但我担心这会导致泄密。
答案 0 :(得分:2)
只有在使用循环引用时才需要使用weak
。我知道你有一个(父母)TreeNode
有TreeNode
个孩子。父母对每个孩子都有强烈的引用,因此从孩子到父母的任何引用都必须是weak
,否则都不会破坏。您已将parentNode
标记为弱。
在rootNode
的情况下,您只需要担心它返回的内容。由于它返回弱_rootNodeCache
,因此您将没有循环引用。您可以使用下面的代码证明这一点。添加或删除rootNode
中的弱点没有任何区别。但是,从_rootNodeCache
或parentNode
中删除弱会导致循环引用并且不会调用deinit。
class TreeNode {
var name: String = ""
var childNodes = [TreeNode]()
weak var parentNode: TreeNode?
private weak var _rootNodeCache: TreeNode?
var rootNode: TreeNode? {
return _rootNodeCache
}
init(_ name: String, _ root: TreeNode?, _ parent: TreeNode?) {
self.name = name
_rootNodeCache = root
parentNode = parent
if let parent = parent {
print("Adding \(name) to \(parent.name)")
parent.childNodes.append(self)
}
}
deinit {
print("deinit \(name) \(childNodes.count) children")
}
func show() {
print("\(name) has \(childNodes.count) children")
for child in childNodes {
child.show()
}
}
}
func addChildren(root: TreeNode) {
let child = TreeNode("child", root, root)
TreeNode("grandchild", root, child)
}
var root: TreeNode? = TreeNode("root", nil, nil)
addChildren(root!)
root!.show()
root = nil