1

I am fairly new to the whole concept of memory management and ARC.

I've recently looked into it and found mixed success.

Firstly it should be noted that some ViewController do deinitialize but I am still learning and cleaning up my application.

However, a common pattern I have noticed is that when I use the line navigationController?.popViewController(animated: true) this does infact deinit a view controller, given if there are no strong references.

However, my issue is that when I use a segue and use performSegue(withIdentifier: "showDetail_Segue", sender: nil) the deinit method is never used/called. (I just have a print statement to indicate whether a view has been deinitalized). In most cases, when I perform a segue, I am passing data to another view controller and as a result, I use the following function override func prepare(for segue: UIStoryboardSegue, sender: Any?) {}.

I have tried to change my segue to navigationController?.pushViewController(VC, animated: true) but my application crashes.

Am I missing something here?

The ViewControllers that deinitliaze when the navigationController is popped also do not deinitialze when performing a segue programmatically.

Could someone please tell me what I'm doing wrong?

Thank you.

  • Hard to say without seeing your performSegue method. My guess would be you're unintentionally creating a strong reference there. – Adis May 27 '19 at 15:47
  • My `perfomSegue` method is like this `override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "details_Segue" { let detailsVC = segue.destination as! DetailsViewController let text = sender as! String detailsVC.textDescription = text } }` – TheApprentice May 27 '19 at 15:49
  • I reread your question and I think I might have understood it wrongly. Lemme type put an answer. – Adis May 27 '19 at 15:51
  • 1
    Sounds like you need to use an unwind segue for returning to a previous ViewController. See [this answer](https://stackoverflow.com/a/27463286/1630618) for how to create and programmatically call an unwind segue. – vacawama May 27 '19 at 17:54
  • @vacawama Exactly what I was looking for! Thank you so much. – TheApprentice May 27 '19 at 22:43

2 Answers2

1

Alright, if I understood you correctly, you might have a misunderstanding on how segues work

Segues cannot be used to go back to the previous viewController in stack

This is pretty important. If you use segues as a way of going back instead of using popViewController you're creating a new instance of the viewController you go back to so deinit is never called since the viewController is still in memory.

Essentially, something like this List -> Details -> List, where you just created another instance of the list with the segue.

Adis
  • 4,292
  • 2
  • 30
  • 36
  • I am performing segues to go to a separate view controller. Some segues are to a `ViewController` in a different `UIStoryboard`. In essence I'm doing this Home -> Product -> Details. Maybe I have a misunderstanding of `deinit`. I'm trying to deallocate memory whenever a new `ViewController` is presented. This only works when I use `popViewController`. – TheApprentice May 27 '19 at 16:07
  • No, the viewController you're going from is not going to deinit, since it's not being removed from the memory. Deinit works only when the controller is destroyed, and memory released - you wouldn't want this for something you need to come back to later. – Adis May 27 '19 at 16:31
  • segues *can* be used to go back, but you need to use an *unwind segue*. – vacawama May 27 '19 at 17:47
  • I stand corrected. – Adis May 28 '19 at 13:34
1

When you call performSegue and this segue is a push to another VC you are creating a new instance of VC, but your navigation stack is still the same you only add the VC to the stack.

Remember:

Stack: [root, vc1, vc2]

vc2.performSegue (push)

Stack: [root, vc1, vc2, vc3]

The class only call the denit when you are dismissing a VC.

I Hope this helps you.