DEV Community

Lou Franco
Lou Franco

Posted on

iOS StackOverflow Deep Dive: Retain Cycle in Closure

Take a look at this StackOverflow question (don't read the answers or comments) -- see if you can see the problem.

Here are the clues I saw:

  1. The title of the question says there is a retain cycle in a closure. It's not always good to trust the questioner, but ....
  2. They show a screen capture of the memory debugger that does show that that a closure is holding a strong reference to something holding it (causing the cycle)
  3. In all of the code shown, there is only one closure. Again, it's not always right to trust the questioner, but still a place to start.

Here's the closure:

   coord.deinitIfNeeded = { [weak self] in
        guard let self = self else { return }
        self.free(coord)
    }

And here is the definition of Coordinator (the class of coord)

class Coordinator {
    var deinitIfNeeded: (() -> ())?

Ok -- this is enough to solve the problem, if you want to try.

Before I get to the answer: I want to give some advice to new programmers: Unless you know better, trust the tools (like the compiler and memory debugger). I'm not saying they are always right, but I am saying they are much more likely than you to be right. While you are learning, start by assuming your code is wrong.

Ok, so the closure is holding a reference to something that is holding a reference to it. The only thing holding reference to it is coord, in the code: coord.deinitIfNeeded = .... So, is the closure holding coord strongly?

Yes, it is.

It captured coord in the body and coord is not specified to be a weak capture. Think about how to fix this and then check your work by looking at the answer.

Top comments (0)