Passing self.method as closure / block


I tried to find explicitly in Swift documentation the behaviour of the following syntax:

For example, after

class Client {

  func connect() {
      // ...
        let conn = NWConnection.init(to: endpoint, using: parameters)
        let queue = DispatchQueue.init(label: "client")
        conn.stateUpdateHandler = self.stateUpdateHandler
      // ...

  func stateUpdateHandler(_ newState: NWConnection.State) {
     // ...

I assume that the stateUpdateHandler setter will retain self in that situation.

Am I right ?

I guess in this case, if the code properly cleans up the networking connection on deinit, the code should be fine (probably, the client will never be deallocated before the NWConnection).

However, is it recommended to preferably use a wrapper closure for stateUpdateHandler that explicitly define self as weak ?

Imho this handler-architecture is a really, really terrible choice, exactly because of the issue you are concerned of: Inheritance might be a little bit old-fashioned, but it wouldn't cause retain cycles...

If you are brave, you might try unowned ;-) - or, if you have something like a disconnect-method, you can set all those handlers to nil when this is called.

Yes, it does capture self strongly.

I'd recommend you write it in the slightly longer form:

        conn.stateUpdateHandler = { self.stateUpdateHandler($0) }

Then you can add the correct [weak self] capture clause, if you need it, and it's clear to anyone who reads this code what you intend to happen.

Terms of Service

Privacy Policy

Cookie Policy