[swift-evolution] $self

Paul Jack paul.jack at pobox.com
Wed Sep 28 18:05:23 CDT 2016


So previously there were a few threads on the "strong self/weak self
dance" but they didn't seem to get anywhere. For instance:

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160201/008713.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160215/010759.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160208/009972.html

...and possibly others.

I'd like to propose something even easier (and more specific) than all
of the above discussions. Specifically, I'd like to introduce a new
automagic closure variable, $self, whose presence in a closure would
cause that closure to weakly capture self in a safe manner.

As a concrete example, let's imagine a UIViewController for a login
form. Under this proposal, the following code:

func viewDidLoad() {
    self.loginForm.onSubmit = {
         let f = $self.loginForm
         $self.startLoginRequest(email:f.email.text, pwd:f.pwd.text)
    }
}

...would be treated by the compiler as equivalent to:

func viewDidLoad() {
    self.loginForm.onSubmit = {
         [weak self] in
         if let selfie = self {
             let f = selfie.loginForm
             selfie.startLoginRequest(email:f.email.text,
             pwd:f.pwd.text)
         }
    }
}

Note the "if let" there: If self no longer exists, the closure does not
execute at all, but if self does exist, then it exists for the entirety
of the execution of the closure (ie, self won't vanish as a side-effect
of some statement in the closure.) I think these semantics obey the
principle of least surprise; $self can be treated by the developer as a
strong reference.

However, that does mean that $self can only be used in a closure that's
(a) Void or (b) Optional. In the latter case, returning nil when self
doesn't exist seems like reasonable/expected behavior.

It would be a compile-time error to use both $self and normal self in
the same closure.

I'd like to keep this simple, meaning $self always does the above and
nothing else. So, if you need an unowned self, you still need the
original syntax; if your closure needs a non-Optional return type, you
still need the original syntax; etc.

Thoughts?

-Paul


More information about the swift-evolution mailing list