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).

* * *

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)

* * *

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

* * *

Does this make sense? What do you think?

— Radek

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to