[swift-evolution] A shortcut for weakly referencing functions

Zach Waldowski zach at waldowski.me
Fri Apr 1 10:57:55 CDT 2016


Responses inline!

Sincerely,
  Zachary Waldowski
  zach at waldowski.me

On Fri, Apr 1, 2016, at 11:09 AM, Radosław Pietruszewski via
swift-evolution wrote:
> Here’s a pattern I find myself doing quite often:
> 
>   1> class Child {
>   2.     var onSomeEvent: () -> Void = { }
>   3. }
>   4> class Parent {
>   5.     let child = Child()
>   6.     init() {
>   7.         child.onSomeEvent = doSomething
>   8.     }
>   9.     func doSomething() {
>  10.     }
>  11. }
> 
> I have some ownership hierarchy of classes (often controllers — view
> controllers — views), where I pass information from children up to
> parents using closures set by the parent.
> 
> I like this pattern because children classes don’t have to be tied to
> knowledge about their parents, and I don’t have to define delegate
> protocols. It’s very clean, and also very easy to set up.
> 
> The only problem is that there’s a strong danger of introducing reference
> cycles.
> 
> With class properties, you can quite easily see the potential for a
> reference cycle and mark references to parents with weak/unowned. And
> with `self` captures in closures, you’re reminded of memory management by
> having to be explicit about `self`. But when passing references from
> parents to children, there’s no way to mark the closure property as
> `weak` (and there’s no reminder of the danger).

I will go ahead and note, at least in terms of writing the proposal, I
don't find this argument very strong. The proposed syntax still requires
you to know about the cycles involved.

> 
> * * *
> 
> Right now, every time I pass a closure down to children, I have to wrap
> my references like so:
> 
> 	{ [unowned self] self.doSomething($0) }
> 
> instead of a neat and simple function reference:
> 
> 	doSomething
> 
> I think it would be useful to have a shortcut syntax for creating weak
> and unowned references to functions, like so:
> 
> 	@unowned(doSomething)
> 
> or perhaps:
> 
> 	#unowned(self.doSomething)
> 
> * * *

I really like the #unowned syntax! It's expressive and in line with
other pieces of Swift sugar. Would +1 if it came to a proposal!

The @ version doesn't make as much sense as it's not an attribute.

> 
> An alternative would be the ability to mark closure properties as weak or
> unowned. Then I could, at the *child* level, say:
> 
> 	unowned let onSomeEvent: () -> Void

I don't particularly think it makes sense, because it is prescriptive.
If some other user in your codebase wanted the cycle, they couldn't get
it. Plus, what would it mean when the closure isn't capturing anything?

> 
> * * *
> 
> Does this make sense? What do you think?
> 
> — Radek
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution


More information about the swift-evolution mailing list