[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
similarly:
* 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() {
print("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()
holder.doExampleLogic()
for i in 0..<15 {
print("\(i):")
if let heldBeeper = holder.beeper {
print("held beeper exists")
} else {
print("held beeper is nil")
}
}
Results:
$ swift beeper.swift
willSet: Optional(beeper.Beeper)
didSet: Optional(beeper.Beeper)
0:
held beeper exists
1:
held beeper exists
2:
held beeper exists
3:
held beeper exists
4:
held beeper exists
5:
held beeper exists
6:
held beeper exists
7:
held beeper exists
8:
held beeper exists
9:
held beeper exists
10:
held beeper exists
11:
held beeper exists
12:
held beeper exists
13:
held beeper exists
14:
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
works?
Mike
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