Search code examples
iosswifteureka-forms

Why is a retain cycle being caused?


I am using Eureka to set up my table view. I have a section with a header:

Section() { [weak self] in
    guard let strongSelf = self else { return }
    var header = HeaderFooterView<MyView>(.nibFile(name: "MView", bundle: nil))
    header.onSetupView = strongSelf.setUpHeader(view:section:)
    $0.header = header
    ...
}

private func setUpHeader(view: MyView, section: Section) {
    // content here doesn't seem to make a difference.
}

For some reason it always sets up a retain cycle on the line header.onSetupView = strongSelf.setUpHeader(view:section:). If I move the code from the setUpHeader(view: MyView, section: Section) function into a block like this, there is no retain cycle:

header.onSetupView = { [weak self] view, section in

}

Why is this??


Solution

  • header.onSetupView = strongSelf.setUpHeader(view:section:)
    

    This line creates a strong reference to strongSelf, which is a strong reference to self, so transitively that creates a strong reference to self in the onSetupView closure.

    Saying it another way, what you've written here is the same as:

    header.onSetupView = { view, section in
        strongSelf.setupHeader(view: view, section: section)
    }
    

    And since strongSelf is a strong reference to self, that's the same thing as strong reference to self:

    header.onSetupView = { view, section in
        self.setupHeader(view: view, section: section)
    }
    

    And just one more way to say it: self cannot be deallocated before strongSelf is, because then strongSelf would be an invalid reference.