swiftenumsretain-cyclestrong-reference-cycle

enum stores data remains stored in the static variable of an enumeration even if the view controller dismisses


I have a problem and do not know what to do. My FirstViewController calls with

let secondVC = SecondViewController()
let navController = UINavigationController(rootViewController: secondVC)
navController.modalPresentationStyle = .automatic
self.present(navController, animated: true)

my SecondViewController. In the SecondViewController, user can make various selections, such as selecting numbers. The selected numbers are stored in a static variable of an enum located in the SecondViewController. (Why I do it this way is not important right now).

enum Numbers {
     static var selectedNumbers: [Int] = []
}

If I return to my FirstViewController with dismiss the SecondViewController and then go back to my SecondViewController, I see that the enum from the SecondViewController still has the user's selection stored. What exactly is the reason for this? And can I somehow prevent or solve this?


Solution

  • According to your expectation, I recommend changing the static to store property in SecondViewController, and a callback to handle if needed, something like:

    class SecondViewController: UIViewController {
        ...
        private var selectedNumbers: [Int] = []
        var onSelectedNumbers: (([Int]) -> Void)?
    }
    

    In FirstViewController, when you pop back from SecondViewController, handle selected here:

    let secondVC = SecondViewController()
    secondVC.onSelectedNumbers = { [weak self] numbers in
        //TODO:
    }
    let navController = UINavigationController(rootViewController: secondVC)
    navController.modalPresentationStyle = .automatic
    self.present(navController, animated: true)
    

    And if you still want to use static one, you can clear static property whenever SecondViewController is dismissed:

    class SecondViewController: UIViewController {
        ...
        func dismissViewController() {
            //TODO: call this function manually
            self.dismiss(animated: true) {
                Numbers.selectedNumbers = []
            }
        }
    }