4

I have a function that accepts a block as a parameter. I can use trailing closures to pass in a block of code, but that closure must use a weak reference when retaining self.

For example, see the initializer of MyClass2:

class MyClass {
    func subscribe(using block: @escaping () -> Void) {
        DispatchQueue.global().async {
            block()
        }
    }
}

let test = MyClass()

class MyClass2 {

    var someProperty = 0

    init() {
        // Weakly referenced
        test.subscribe { [weak self] in
            self?.update()
        }
    }

    func update() {
        self.someProperty += 1
    }
}

MyClass2()

However, is this still needed if I pass in the closure as a function parameter like this?:

class MyClass2 {

    var someProperty = 0

    init() {
        // Avoid retain cycle?
        test.subscribe(using: update)
    }

    func update() {
        self.someProperty += 1
    }
}
TruMan1
  • 33,665
  • 59
  • 184
  • 335

1 Answers1

4

The entire premise of your question ("but that closure must use a weak reference") is false. There was never any reason to use weak self in your first code. This would be perfectly reasonable:

init() {
    test.subscribe {
        self.update()
    }
}

The reason for needing to use weak self is that the closure referencing self is itself retained by self, causing a retain cycle; but that is not happening here.

matt
  • 515,959
  • 87
  • 875
  • 1,141