Jared
Jared

Reputation: 4810

How could I prevent duplicate references to class objects in an array?

I'm looking for a way to prevent an array from having duplicate references to the same object in it. I don't mean duplicate values - that would be fine.

For example, I know in Apple's SpriteKit framework, an SKNode object stores its children in an array (var children: [SKNode]), and adding a node to a parent twice causes the program to crash.

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.

This is the exact kind of behavior I am wanting to emulate. How would I manage this? Is it possible without having O(n) complexity from having to compare each reference?

Upvotes: 0

Views: 106

Answers (1)

Alexander
Alexander

Reputation: 63271

I'm not sure why exactly you would want to do this, but here is how you can go about doing it:

...

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()
}

Upvotes: 1

Related Questions