是否应使用' weak'指定计算属性?什么时候引用弱-ref变量?

时间:2016-03-02 02:15:14

标签: swift swift2

我已经构建了一个树,其树节点如下所示:

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? 没有弱点就可以跑。但我担心这会导致泄密。

1 个答案:

答案 0 :(得分:2)

只有在使用循环引用时才需要使用weak。我知道你有一个(父母)TreeNodeTreeNode个孩子。父母对每个孩子都有强烈的引用,因此从孩子到父母的任何引用都必须是weak,否则都不会破坏。您已将parentNode标记为弱。

rootNode的情况下,您只需要担心它返回的内容。由于它返回弱_rootNodeCache,因此您将没有循环引用。您可以使用下面的代码证明这一点。添加或删除rootNode中的弱点没有任何区别。但是,从_rootNodeCacheparentNode中删除弱会导致循环引用并且不会调用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