Strong control cycles for closures in Swift

I have defined a class called Person

. This is my code:

    class Person { 
        var closure: (() -> ())?
        var name: String

        init(name: String) {

            self.name = name
            print("\(name) is being initialized")
        }

        deinit {
            print("\(name) is being deinitialized")
        }
    }

      

then i use Person

in a class called ViewController

:

class ViewController: UIViewController {

    var person = Person(name: "john")
    let aStr = "john is a cute boy"


    override func viewDidLoad() {
        super.viewDidLoad()

        person.closure = {
            print("\(self.aStr)")
        }
        person.closure!()
    }
}

      

In my opinion, the memory picture of my code looks like this: memory

So from my point of view, this, in my opinion, will result in a strong reference cycle between 3 instances, but I cannot get a leak from Instruments

, so I have some confusion.

Is this code calling a strong reference loop?

If not, when will ARC release the instance Person

? a named method deinit

in a class is Person

never called.

+3


source to share


1 answer


Yes, this is a typical save cycle.

To solve this problem use [weak self]

in your closure

person.closure = { [weak self] in
    guard let strongSelf = self else { return }
    print("\(strongSelf.aStr)")
}

      




To really create a leak.
I am creating a demo application. Root is navController.
The navController has a root controller. Let's call it buttonController. When you click a button in buttonController, it creates your ViewController and clicks the nav Navigator. When you click the back button on the navigation bar, the navController exposes your ViewController instance.

Profile this then you will see the leak and hold cycle in the Tools.

The default Xcode template of an iOS app uses a single page that always saves your ViewController instance. If the ViewController instance is still in use by the system, it isn't actually leaking yet. So hit and pop that leak show for you.

+2


source







All Articles