【问题标题】:How could I prevent duplicate references to class objects in an array?如何防止重复引用数组中的类对象?
【发布时间】:2017-11-14 16:15:54
【问题描述】:

我正在寻找一种方法来防止数组重复引用其中的同一对象。我的意思不是重复值 - 这很好。

例如,我知道在 Apple 的 SpriteKit 框架中,一个 SKNode 对象将其子对象存储在一个数组 (var children: [SKNode]) 中,两次向父对象添加一个节点会导致程序崩溃。

let parent = SKNode()
let child1 = SKNode()
let child2 = SKNode()
parent.addChild(child1)
parent.addChild(child2)    // Allowed, although child2 == child1.
parent.addChild(child1)    // Causes a crash.

这正是我想要模仿的行为。我将如何管理这个?是否有可能无需比较每个引用而产生 O(n) 复杂度?

【问题讨论】:

    标签: swift


    【解决方案1】:

    我不确定您究竟为什么要这样做,但您可以这样做:

    ...
    
    var childReferences = Set<ObjectIdentifier>
    
    private func validateUniqueness(_ node: SKNode) {
        guard childReferences.insert(ObjectIdentifier(node)).inserted else {
            fatalError("An attempt was made to add a duplicate child")
        }
    }
    
    override func addChild(_ node: SKNode) {
        validateUniqueness(node)
        super.addChild(node)
    }
    
    override func insertChild(_ node: SKNode at index: Int) {
        validateUniqueness(node)
        super.insertChild(node, at: index)
    }
    
    override func removeChildren(in nodes: [SKNode]) {
        childReferences.subtract(nodes)
        super.removeChildren(in nodes: [SKNode])
    }
    
    override func removeAllChildren() {
        childReferences.removeAll(keepingCapacity: false)
        super.removeAllChildren()
    }
    

    【讨论】:

    • 我认为 OP 询问是否可以在没有 O(n) 复杂性的情况下做到这一点。但是您只是使用set,它只是在添加之前检查重复项,因此最坏情况的复杂度仍然是 O(n)。
    • @ebby94 在Sets 中的查找是O(1)
    • 不知道。但是Set 的查找 O(1) 怎么样?使用下标访问具有 O(1) 复杂度,但查找重复项应该需要 O(n) 复杂度,对吧?任何解释这一点的链接都会很酷:)
    • Accessing with a subscript has a O(1) complexity 下标可以实现任意行为,因此不能保证它们是 O(1)。特别是对于Array,索引乘以元素大小,并添加到基指针。这恰好是一个常数时间操作,但其他类型可以实现具有更高时间复杂度的下标。例如,链表可以实现 O(N) 的下标。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-24
    • 1970-01-01
    相关资源
    最近更新 更多