[swift-users] Checking whether an object is uniquely referenced, using a weak reference to it
Dave Abrahams
dabrahams at apple.com
Tue Jun 28 20:18:49 CDT 2016
on Tue Jun 28 2016, Andrew Trick <atrick-AT-apple.com> wrote:
>> On Jun 28, 2016, at 9:32 AM, Jordan Rose via swift-users <swift-users at swift.org> wrote:
>>
>>
>>> On Jun 27, 2016, at 18:52, Tim Vermeulen <tvermeulen at me.com> wrote:
>>>
>
>>> Thanks for your reply. It didn’t clear up everything, though. The
>>> official documentation says "Weak references do not affect the
>>> result of this function.”, which suggests that weak (and unowned)
>>> references intentionally aren’t counted. The docs only mention the
>>> implementation of copy-on-write behaviour as a use case (which also
>>> happens to be what I’m using it for).
>>
>> I would expect that weak references are important to count for COW,
>> since you can observe changes through them. Dave?
>>
>>
>>>
>>> Couldn’t there just a be a function that returns the reference
>>> count of a given object as an Int? It would make everything a lot
>>> easier (i.e. it wouldn’t need inout because it can just create a
>>> reference to that object, find the reference count, then subtract
>>> 1).
>>
>> As we’ve said for a long time in Objective-C, asking for the
>> reference count of an object is meaningless. isUniquelyReferenced
>> only works because it’s conservative: because it only checks for
>> “exactly 1”, it’s safe from threading issues and autorelease
>> pools. We do not plan to add a -retainCount equivalent to Swift.
>>
>> Jordan
>
> Specifically, isUniquelyReferenced guarantees “exactly 1” if it
> returns ‘true’. It does not guarantee ‘> 1’ by returning ‘false’. In
> other words, the implementation reserves the right to return ‘false’
> whenever it feels like it. The user can’t directly control the number
> of local references that exist. So, although it’s critical for
> optimization, you shouldn’t build any visible program behavior around
> isUniquelyReferenced.
>
> I don’t have a good answer on the weak reference semantics, but I
> *suspect* that considering weak references in the count is neither
> feasible for objc-style weak references, nor useful since we don’t
> expose weak references to CoW storage.
We have a race in this case:
class X {}
var a = [X()]
weak var b = a as NSArray
async {
// Reads the buffer through the weak reference in another thread.
print(b!.object(at: 0))
}
// Sees that a's buffer is uniquely referenced and begins to modify it
// in place.
a[0] = X()
So yes, isUniquelyReferenced should always be false if the weak
reference count is nonzero. We can read the weak and strong reference
counts together with a single instruction so this should be easily
implementable. We just haven't done it. <rdar://problem/27070378>
--
Dave
More information about the swift-users
mailing list