Friday, August 4, 2023

Avoiding Implicit Retain Cycles When Using Swift Function References

Svein Halvor Halvorsen:

Even though we capture self unonwed in the outer closure, the callbacks that gets registered with the socket, are captured strongly. So even when the object above is released from where ever it was created, the object is still kept alive.


The [unowned self] in and argument list is just boilerplate, repeated over, with no other purpose than to pass arguments from one function (the in-line closure) on to the next (the actual event handler functions).


What if we took self.dynamicType.onChatMessageReceived from the second event handler above, but without the argument (self), and passed that as a parameter to our wrapper function, together with a reference to self? Maybe we could then capture that reference unowned, and pass the unowned instance reference to the class function to get an instance function, without creating a retain cycle.

As he says, this works but it is far from optimal. I wonder if there’s a way to make it better with macros.

Sean Heber:

In the first line, Swift will helpfully tell me that I’m accidentally capturing self, but in the second line there’s no warning whatsoever.


Update (2023-08-09): Doug:

I’ve hit that enough to make a helper library and there’s a forum discussion proposing a syntax for weakly capturing a method that’s quite relevant.

However, the last post was more than 5 years ago.

Update (2023-08-15): See also: Revisiting requiring explicit self. when passing a method as an escaping closure (via Robin Kunde).

Comments RSS · Twitter · Mastodon

Leave a Comment