When using self in the completion block, does it always have a memory leak in Swift?

39 Views Asked by At

I've been working on Swift for about half a year, and now I struggle with understanding when to use the [weak self] to avoid a memory leak. TBH, it was too difficult for me to understand from the document or other people's articles, so I used this video to figure out when to use it. I kinda understood when to use the [weak self] but not 100% sure its usage.

In the video, for instance, the guy created an alert controller in the view controller.

class TestVC: UIViewController {
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "done", style: .cancel, handler: { _ in
            self.doSomething()
        }))
        
        present(alert, animated: true)
    }
    
    func doSomething() {
        // do something
    }
}

He explains that

  • the view controller creates the alert
  • when the done button is pressed, in the handler closure, it references self, which is a view controller.

So in the above, I get I must use [weak self] to deallocate the view controller. However, now I'm confused with when not to use the weak self.

For instance, say I have a view controller with a function to animate the view.

class TestVC: UIViewController {

    let testView = TestView()
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        changeViewHeight()

    }
    
    func changeViewHeight() {
        UIView.animate(withDuration: 3) {
            self.testView.heightConstraint?.constant = 40
            self.view.layoutIfNeeded()
        }
    }
}

So in the code above, since the TestVC has a reference to changeViewHeight function, and in the completion block of the animate function, it points back to TestVC using self, should I change it to [weak self]?

Also, I think any function with a completion block has a chance to use self in the completion block, but that time is the retain cycle is happening and I should consider using [weak self] whenever I use self in the completion block? (which I guess it's not, but cannot explain why, so if someone can explain please let me know.)

0

There are 0 best solutions below