Implicit retain cycle in lazy var
When writing Swift code, it's easy to to create retain cycles if you're not careful. It usually happens when a closure has a strong reference to self and self has a strong referenc to the the closure.
So just need to take note of all the self references in closure blocks, easy-peasy, right?. But today, I found a new kind of retain cycle I didn't noticed before.
class API {
    var status: String?
    
    var failureHandler: (() -> Void)?
    var completionHandler: (() -> Void)?
    
    init() {}
}
class ViewController: UIViewController {
    lazy var api: API = {
        let api = API()
        api.completionHandler = {
        }
        api.failureHandler = {
            // `api` reference Cause retian cycle
            // Use `self.api` instead of 'api' to fix it
            print(api.status ?? "")
        }
        
        return api
    }()
}
Here there is no self reference, but because api returned by the lazy closure is later referenced by self, a retain cycle is created.
Member discussion