Reference identity

I’m not sure if I’m asking the right question, but …

I have a need for a collection that’s basically a set of objects (instances of reference types), where member equality is reference-equality not Equatable-equality. So, perhaps a set whose members are wrapped something like this:

struct ObjectReference: Equatable, Hashable {
	let object: AnyObject
	

	static func == (lhs: ObjectReference, rhs: ObjectReference) -> Bool {
		return lhs.object === rhs.object
	}
	
	var hashValue: Int {
		return 0
	}
}
let set = [ObjectReference(object: a), ObjectReference(object: b)]

This works, but obviously isn’t workable because of the hashValue implementation. Kind of by accident, I tried this:

	var hashValue: Int {
		return object.hash!
	}

(using AnyObject dispatch to — I suppose — the NSObject hash property via bridging). Somewhat surprisingly, it works for Swift-native reference types as well as actual NSObject types.

Is this something I can rely on? Is there bridging overhead? Is there a better way to get a set of objects respecting reference equality?

ObjectIdentifier is useful for this:

var hashValue: Int {
    return ObjectIdentifier(object).hashValue
}

If you don’t ever need to read the object property, you could even use ObjectIdentifier instead of your ObjectReference struct.

2 Likes

Ah, yes, thank you! Now that you mention it, I remember having seen it before.