I'm not sure if I get your exact use case, but if you do this:
socket.on("event", handler: self.eventHandler)
… this is equivalent to:
socket.on("event") { self.eventHandler($0) }
… then you'll create a retain cycle if self
owns the socket, since it registers a closure which strongly captures self
. The reason it has to capture self is that the event handler is an instance method, and may in its body use self
. It it equivalent to this:
socket.on("event") { Self.eventHandler(self)($0) }
But if you instead do:
socket.on("event") { [weak self] in self?.eventHandler($0) }
… it may seem like it is equivalent, but it is not. It is a no-op which is silently dropping events when self goes away.
I totally see how it must be like this, but I wish there would be syntax to make this a little more ergonomic. This is particularly true when the function takes several arguments. Then it it tedious to keep writing: { [weak self] in self.eventHander($0, $1, $2, $3) }
instead of just passing self.eventHandler
as a simple function reference.
It is possible to exploit the fact that instance methods really are just curried static functions on the type, and write a wrapper function weakify
that takes a static function and an instance (that it captures weakly). You can then replace self.eventHandler
with weakify(Self.eventHandler)
. Notice the uppercase S
.