I have an object pool (that requires getting the objects out of a Dictionary for various reasons) and I need to determine if they're uniquely referenced when I get them out, or else they may still be in use. I've played around with lots of things like:
if cache[id] == nil {
let object = MyObject()
cache[id] = object
return object
}
unowned(unsafe) var object = cache[id]!
if isKnownUniquelyReferenced(&object) {
return object
}
However, this always returns false for isKnownUniquelyReferenced, even when there don't seem to be any references besides that of the map's. Any ideas what to do?
isKnownUniquelyReferenced(_:) checks only for strong references to the given object—if object has additional weak or unowned references, the result may still be true . Because weak and unowned references cannot be the only reference to an object, passing a weak or unowned reference as object always results in false .
You can get the address of elements of a dictionary directly, so isKnownUniquelyReferenced(&cache[id]) should work.
EDIT: Works for me (in a compiled app; playgrounds are not reliable for reference counting):
class MyObject {}
var cache = [Int: MyObject]()
do {
var obj = MyObject()
if isKnownUniquelyReferenced(&obj) {
print("1 - Unique")
} else {
print("1 - Not unique")
}
cache[3] = obj
}
if isKnownUniquelyReferenced(&cache[3]) {
print("2 - Unique")
} else {
print("2 - Not unique")
}
do {
let obj = cache[3]
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(10), execute: { _ = obj })
if isKnownUniquelyReferenced(&cache[3]) {
print("3 - Unique")
} else {
print("3 - Not unique")
}
}