[swift-evolution] Proposal: Give weak references the ability to notify reference-holders when they transition to nil

Michael Henson mikehenson at gmail.com
Mon Dec 14 22:19:10 CST 2015

Something occurred to me while I was thinking through a response to the
thread issue. The language already provides a couple of things that behave

* deinit methods
* property setters

I couldn't find a documented guarantee for either of them to run on a
particular thread, or any explicit detail on guarantees of behavior in
threaded environments.

Given that every weak reference has to be an Optional type, I ran the
following test code to see if setters are called when a weak reference
becomes nil:

// swift-2.2-SNAPSHOT-2015-12-10-a-ubuntu15.10
import Glibc

class Beeper {
  func beep() {

class Holder {
  weak var beeper: Beeper? {
    willSet {
      print("willSet: \(newValue)")
    didSet {
      print("didSet: \(beeper)")

  func doExampleLogic() {
    // so there was, at one time, a strong reference in this context
    let beeper = Beeper()
    self.beeper = beeper

let holder = Holder()

for i in 0..<15 {

  if let heldBeeper = holder.beeper {
    print("held beeper exists")
  } else {
    print("held beeper is nil")

$ swift beeper.swift
willSet: Optional(beeper.Beeper)
didSet: Optional(beeper.Beeper)
held beeper exists
held beeper exists
held beeper exists
held beeper exists
held beeper exists
held beeper exists
held beeper exists
held beeper exists
held beeper exists
held beeper exists
held beeper exists
held beeper exists
held beeper exists
held beeper exists
held beeper exists

I see the exact same results if I compile with swiftc. I expected the
weakened optional to set itself to nil when the strong reference went out
of scope at the end of doExampleLogic(). Have I misunderstood how weakening


On Mon, Dec 14, 2015 at 1:06 PM, Greg Parker <gparker at apple.com> wrote:

> > On Dec 13, 2015, at 6:24 PM, Michael Henson via swift-evolution <
> swift-evolution at swift.org> wrote:
> >
> > The use-case for this comes first from proposals to have a
> weak-reference version of collection types. Implementing a notification
> signal of some sort to weak reference-holders when the reference becomes
> nil would make implementing those more straightforward.
> How do you want this to work in the presence of threads?
> One option is that the nil transition and the callbacks are performed
> together, synchronously and atomically with respect to some things. The
> problem with this scheme is that the callback is limited in what it can do.
> If it does the wrong thing it will deadlock. The definition of "wrong
> thing" depends in part on the definition of "atomically with respect to
> some things". For example, if the callbacks are called atomically with
> respect to other weak reference writes then the callback must not store to
> any weak references of its own.
> Another option is that the callbacks are performed asynchronously some
> time after the nil transition itself. (Java's PhantomReference offers
> something like this.) The problem with this scheme is that the state of the
> world has moved on by the time the callback is called, which can make the
> callback difficult to write. In particular there is no guarantee that the
> weak variable's storage still exists when the callback for that weak
> variable is executed.
> --
> Greg Parker     gparker at apple.com     Runtime Wrangler
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151214/88d23114/attachment.html>

More information about the swift-evolution mailing list