[swift-evolution] Proposal: Allow `[strong self]` capture in closures and remove the `self` requirement therein

David Rodrigues david.ndh at gmail.com
Tue Dec 15 20:02:20 CST 2015


+1 from me. I think this complements the options that we already have,
[weak self] and [unowned self], but we're dependent on the result of SE-0009
<https://github.com/apple/swift-evolution/blob/master/proposals/0009-require-self-for-accessing-instance-members.md>
which affects the viability of this change.

2015-12-16 1:42 GMT+00:00 Marc Knaup via swift-evolution <
swift-evolution at swift.org>:

> +1 from me. Developers will likely only ever write the rather uncommon [strong
> self] capture when they know what they are doing.
> Misuse can happen with any feature, but it is unlikely in this case.
>
> On Wed, Dec 16, 2015 at 12:02 AM, Greg Parker via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> Swift currently requires that `self` be used explicitly inside closures,
>> to help avoid bugs from unintentional capture. This is annoying when a
>> closure uses `self` a lot. Closures should be allowed to name `[strong
>> self]` in their capture list and thereafter not be required to write `self`
>> everywhere.
>>
>> I wrote code this weekend that looked something like this:
>>
>>     data = ...
>>     running = true
>>     delegate.notifyBegin(data)
>>
>>     dispatch_async(queue) {
>>         self.processData(self.data)
>>         self.running = false
>>         self.delegate.notifyEnd(self.data)
>>     }
>>
>> Note the asymmetry: the dispatched code needs to use `self` and the
>> non-dispatched code does not. It is clear that the dispatched closure
>> captures `self`, but it's annoying that it needed to be mentioned five
>> different times. The noise gets worse with longer closures. The annoyance
>> gets worse when moving code in and out of dispatches or other closures,
>> with lots of editing required each time.
>>
>> The proposal would allow the same code to be written like this:
>>
>>     data = ...
>>     running = true
>>     delegate.notifyBegin(data)
>>
>>     dispatch_async(queue) {
>>         [strong self] in
>>         processData(data)
>>         running = false
>>         delegate.notifyEnd(data)
>>     }
>>
>> Advantages:
>> * The dispatch'ed code looks like the non-dispatched code.
>> * The capture of `self` is still obvious.
>> * The code's action is clearer without the `self` noise.
>>
>> Disadvantages:
>> * The capture behavior of self's properties is less obvious. For example,
>> neither closure above captured its own copy of `self.data`, but that
>> behavior is not immediately visible in the second closure.
>>
>>
>> What about [weak self] and [unowned self] ? I do not propose to change
>> the `self` requirement for those closures. In the weak case it is
>> critically important to know where `self` is accessed, because it could
>> potentially become nil between any two accesses. Unowned self might be
>> reasonable to change, but for simplicity I won't do so here.
>>
>>
>> --
>> Greg Parker     gparker at apple.com     Runtime Wrangler
>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151216/3007ee70/attachment.html>


More information about the swift-evolution mailing list