Closures argument + member function = retain cycle?

After introducing ARC memory management was simplified a lot, but still could not be forgotten. For sure every developer working with either Objective-C or Swift had to deal with retain cycles. There are lots of in depth posts about this topic and I do not want to rephrase them, so instead I will link to my favourite from krakendev. Unfortunately this post does not cover everything and I would like to mention some specific case which I encountered not that long ago.

Imagine following example, where private member function is passed as a closure argument:

The problem with the above code is that sendRequest returns its result using @escaping closure from a background queue.
Passing a private handleResponse function as a closure argument creates a retain cycle, hence deinit is never called on Dispatcher object.

The problem could be easily solved by either:

  • inlineing handleResponse content withing the closure where self is weak/unowned
  • wrapping handleResponse with another closure where self is weak/unowned

The above code looks ugly and is less compact. What if we created a helper function allowing us to wrap up this code?

and then use the following code?

Not perfect, but definitely more compact. Anyway, I think that this is something that could be addressed in new version of Swift.

Check out my GitHub project with Swift One-Liners, where you can find this exemplary wrapper, extended with versions having different closure signatures.

If you enjoyed this article, please follow me on twitter: @tgebarowski