[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> 


More information about the swift-users mailing list