2

In Swift, I'm currently facing the issue where I need to often wrap functions in closures in order to prevent strong reference cycles when passing on a class's function as a closure parameter. For example, in the scenario below:

class A {
    var foo: () -> Void
}

class B {

    private let a: A

    init() {
        self.a = A()
        a.foo = { [weak self] in self?.foo() } // <- Can this be simplified, while still avoiding strong reference cycles?
    }

    private func foo() {}

}

Having to always type { [weak self] in self?.myFunc() } is not nice, as it opens the door people accidentally introducing memory leaks as they forgot to wrap myFunc in a closure. Is there an easier/more foolproof way that similar behavior can be achieved?

-- Edit

If no easier way exists, I will likely open up a feature request @ Apple for syntax that looks something like:

init() {
    self.a = A()
    a.foo = weak foo
}

where a.foo = weak foo is equivalent to a.foo = { [weak self] in self?.foo() }

Or, when dealing with functions that aren't owned by self:

let b = B()
let a = A()
a.foo = weak b.foo

where a.foo = weak b.foo is equivalent to a.foo = { [weak b] in b?.foo() }

Note: I am not proposing to make closures themselves weakly referencable. I'm simply proposing that weak b.foo is compiled identically to { [weak b] in b?.foo() }

ImJustACowLol
  • 826
  • 2
  • 9
  • 27
  • If you want to use an instance method of Class B to set the foo property of A, as far as I know, this is the only way to do it without causing memory leaks. There is a discussion going on though to make closure properties weak https://forums.swift.org/t/weak-closure-reference/16085 – Anirudh Bandi Apr 14 '20 at 15:27
  • @AnirudhBandi what is proposed in that topic is slightly different though. In that discussion, they propose to make closures a reference-type, which I do not propose. What I propose, is that some syntax sugar is introduced so that `a.foo = weak b.foo` is compiled equivalently to `a.foo = { [weak b] in b?.foo() }`. The difference is that in the discussion you are pointing to, they propose to store the closure as a whole weakly. I'm proposing to still box the closure, but hide that from the programmer. – ImJustACowLol Apr 14 '20 at 15:42
  • I have found this discussion on Swift Forums, but no solution for your problem. https://forums.swift.org/t/implicit-retain-cycle/15238/10 – Witek Bobrowski Apr 14 '20 at 17:12

0 Answers0