Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

theprizerevealed

macrumors regular
Original poster
Feb 26, 2016
183
12
I'm coding an app where the view controller will present a question and there are a series of answers. After an answer has been chosen by clicking a button then part of the code of the button will instantiate a new view controller to do the same thing again. This is proving to be a problem because it is being a memory hog according to xcode.

How can I 'dismiss' the old view controller that was just replaced by the instantiation so that the memory is freed?
 
IMO a better design would be to refresh the view controller with the contents of the next question. Either fade from the current question to the next question or use a scrollview and scroll in the next question from the right side of the screen.
 
  • Like
Reactions: deadworlds
Agreed. A single view controller that simply displays the question and answers, then changes them after each answer is chosen, makes much more sense. If you are using multiple view controllers just to get animation transitions, there are easy ways to i simulate that behavior with a single view controller (e.g. by using child views that hold the current and next content, then animating the current child view off screen while simultaneously animating the new one on screen, etc.)
 
I'm not sure but I think that this might be a lot of work. Basically, I have what I think is called a rootviewcontroller (which is a menu with switches and a button)

This rootviewcontroller segues to another view controller with a View and multiple buttons. After a button is pressed then after a bunch of other operations it instantiates a new view controller.

All that (I think) that I need to do is free the memory from the presenting viewcontroller. It will never revisit that presenting viewcontroller. I just need some code to do that. I have read about

Code:
  dismiss(animated: <#T##Bool#>, completion: <(() -> Void)?(() -> Void)?##() -> Void#>)

But that code simply brings me back to the rootviewcontroller (which is a menu with switches and a button).

I have tried ViewDidAppear but it causes some of my variables and arrays to go out of bounds .

I have read about deinit() but I don't know where to put that code or what to write inside it to make it free the memory of the presenting/parent viewcontroller.

I really don't wish to rewrite the code for the viewcontroller from scratch so any other suggestions would be helpful.
 
I'm not sure but I think that this might be a lot of work. Basically, I have what I think is called a rootviewcontroller (which is a menu with switches and a button)

This rootviewcontroller segues to another view controller with a View and multiple buttons. After a button is pressed then after a bunch of other operations it instantiates a new view controller.

All that (I think) that I need to do is free the memory from the presenting viewcontroller. It will never revisit that presenting viewcontroller. I just need some code to do that. I have read about

Code:
  dismiss(animated: <#T##Bool#>, completion: <(() -> Void)?(() -> Void)?##() -> Void#>)

But that code simply brings me back to the rootviewcontroller (which is a menu with switches and a button).

I have tried ViewDidAppear but it causes some of my variables and arrays to go out of bounds .

I have read about deinit() but I don't know where to put that code or what to write inside it to make it free the memory of the presenting/parent viewcontroller.

I really don't wish to rewrite the code for the viewcontroller from scratch so any other suggestions would be helpful.

It’s impossible to tell what’s going on without seeing your code. If you insist on creating a new view controller just to display new data the same way, make sure you free up all the memory you can in viewWillDisappear.
 
Imagine a web browser. It's very much like what you're doing. Does it push a new view controller for each new web page or does it replace the current screen with a new screen?
 
  • Like
Reactions: MisterSavage
It’s impossible to tell what’s going on without seeing your code. If you insist on creating a new view controller just to display new data the same way, make sure you free up all the memory you can in viewWillDisappear.


But how do I free memory? What code do I use and how do I write it? Is it something related to deinit or dealloc?

Or am I supposed to reset every variable to zero's or empty strings, or empty arrays or what exactly?
 
But how do I free memory? What code do I use and how do I write it? Is it something related to deinit or dealloc?

Or am I supposed to reset every variable to zero's or empty strings, or empty arrays or what exactly?

Are you writing in swift or objective C? What objects are you creating and how are you retaining them? It’s tough to answer your questions without knowing your code. With modern code, objects are automatically retained until nothing is referencing them, and then they are automatically deleted. I suspect your code is pushing each view onto a stack of a navcontroller so they can’t be released. Which is why everyone keeps telling you to fix the code to do it the way it is intended - one viewcontroller that updates its subviews.
 
  • Like
Reactions: deadworlds
You mention that doing a view that updates it’s content is too much work. I think this is a bad way of viewing it. When you program and make an app the shortes and fastest way of accomplishing something while ignoring best practices is a recipe for disaster.

As you’ve already found, instantiatiing a new view for each question takes up an increasing amount of memory, which is why you usually don’t ever want to go that route

I strongly suggest that you download apples book App Develoment with Swift from the iBooks store, it’s free!

Check out the guided project on page 398, it covers how to have 1 view that updates it’s contents to display a different question along with answers. You should find this very helpful if this is similar to what you are trying to accomplish.
 

Attachments

  • EA10F898-E538-483D-B568-0C94EC641008.png
    EA10F898-E538-483D-B568-0C94EC641008.png
    2.4 MB · Views: 237
  • DB4488D8-81FB-4820-BBC7-C0BAC9D5F257.png
    DB4488D8-81FB-4820-BBC7-C0BAC9D5F257.png
    490.7 KB · Views: 194
Are you writing in swift or objective C? What objects are you creating and how are you retaining them? It’s tough to answer your questions without knowing your code. With modern code, objects are automatically retained until nothing is referencing them, and then they are automatically deleted. I suspect your code is pushing each view onto a stack of a navcontroller so they can’t be released. Which is why everyone keeps telling you to fix the code to do it the way it is intended - one viewcontroller that updates its subviews.


I'm coding with Swift in Xcode. From what little I read so far, it seems you might be correct that they're being pushed onto a stack of a navcontroller (though I'm still hazy about what that means really)
[doublepost=1548828398][/doublepost]
You mention that doing a view that updates it’s content is too much work. I think this is a bad way of viewing it. When you program and make an app the shortes and fastest way of accomplishing something while ignoring best practices is a recipe for disaster.

As you’ve already found, instantiatiing a new view for each question takes up an increasing amount of memory, which is why you usually don’t ever want to go that route

I strongly suggest that you download apples book App Develoment with Swift from the iBooks store, it’s free!

Check out the guided project on page 398, it covers how to have 1 view that updates it’s contents to display a different question along with answers. You should find this very helpful if this is similar to what you are trying to accomplish.


Thank you so much for informing me about these resources - I wasn't aware of them before. I downloaded copies today and I will study them immediately.
 
  • Like
Reactions: deadworlds
Is this still accurate and current?

https://www.reddit.com/r/iOSProgramming/comments/2p4qzl/view_controller_instantiation_and_memory/

level 1
zRobertez
1 point · 4 years ago


"You'll have to double check this but in Instruments, with an app with a lot of images, you can notice a lot of image objects adding up. I did some research a while back (I noticed that too) and this image memory kept just stacking up. But it looks like Obj-C or Apple or somewhere keeps images (among other things) still partially loaded even when they are not needed. So that if they are needed again soon, it is more efficient to use what is in memory. This "cache" of stuff is eventually freed up as other things need to access those resources.

Also, when testing for this in the simulator, you'll notice a larger than expected chunk of this image memory because the sim uses your computer's resources, which there are a lot more of. If you're noticing performance issues on a real device with limitations (less RAM) then watch for those image allocations to plateau or reduce. If that happens, then your issue is somewhere else. If you aren't noticing performance issues, I wouldn't worry about it though the advice in the other comments is good to adjust to as well. :)"
 
Is this still accurate and current?

https://www.reddit.com/r/iOSProgramming/comments/2p4qzl/view_controller_instantiation_and_memory/

level 1
zRobertez
1 point · 4 years ago


"You'll have to double check this but in Instruments, with an app with a lot of images, you can notice a lot of image objects adding up. I did some research a while back (I noticed that too) and this image memory kept just stacking up. But it looks like Obj-C or Apple or somewhere keeps images (among other things) still partially loaded even when they are not needed. So that if they are needed again soon, it is more efficient to use what is in memory. This "cache" of stuff is eventually freed up as other things need to access those resources.

Also, when testing for this in the simulator, you'll notice a larger than expected chunk of this image memory because the sim uses your computer's resources, which there are a lot more of. If you're noticing performance issues on a real device with limitations (less RAM) then watch for those image allocations to plateau or reduce. If that happens, then your issue is somewhere else. If you aren't noticing performance issues, I wouldn't worry about it though the advice in the other comments is good to adjust to as well. :)"

I think the first response in that reddit post is the right one. The code in that post just keeps pushing more and more viewcontrollers onto a stack. That’s not how you should do things. You are pushing one viewcontroller on top of another. You are creating an infinite pile. You cant then go and delete the ones in the bottom of the pile because you will screw up the navcontroller data structures, etc.

Again, the right way to do what you are trying to do is to have a single view controller, have it update its views based on whatever the next set of data is, and, if you must have fancy animations just use core animation to keep a second set of views that swoops in to replace the old ones (and you can then re-use the old views as the next new views).

Your fundamental architecture is wrong.
 
I think the first response in that reddit post is the right one. The code in that post just keeps pushing more and more viewcontrollers onto a stack. That’s not how you should do things. You are pushing one viewcontroller on top of another. You are creating an infinite pile. You cant then go and delete the ones in the bottom of the pile because you will screw up the navcontroller data structures, etc.

Again, the right way to do what you are trying to do is to have a single view controller, have it update its views based on whatever the next set of data is, and, if you must have fancy animations just use core animation to keep a second set of views that swoops in to replace the old ones (and you can then re-use the old views as the next new views).

Your fundamental architecture is wrong.

Well, I tried reprogramming in such a way as to dismiss viewcontrollers all the way back to the rootviewcontroller from which they were instantiated however the memory usage seems to remain the same approximately. I think that there must be something to the post above... most of the views are displaying images of varying sizes.
 
Trust us, we know what we’re talking about. I suggest you go through the whole Apple app development book I suggested a few posts above. It will give you a much much better understanding as to how programming works and why you shouldn’t be doing what you’re trying to do.
 
Well, I tried reprogramming in such a way as to dismiss viewcontrollers all the way back to the rootviewcontroller from which they were instantiated however the memory usage seems to remain the same approximately. I think that there must be something to the post above... most of the views are displaying images of varying sizes.
I’ve written apps that display thousands of images and yet the apps still have constant memory usage. You are doing something wrong. You aren’t actually releasing every object you think you are releasing. You are stubbornly clinging to doing things the wrong way. If you do it the way it’s intended to be done, there will be no chance of such problems.
 
I'm not stubbornly clinging to anything. I do what works. You haven't said anything to refute the reddit poster's observations.

Does dismiss deal with with all objects in a viewcontroller or not?

Among the programming changes I did was to reinitialize all variable values to zero, or empty strings, empty arrays, nil values for uiimages, etc. Yet the memory stays the same.

If there is some other way to release memory than dismissing the entire stack of viewcontrollers back to the root viewcontroller - or resetting all variables then it would be helpful if you could cite some code as they do at stackoverflow website.

As I explained before there is simply a uiview and some buttons in my view controller. If there is some code that causes these to be removed from memory then certainly I would be glad to implement it.

Here's an example of the kind of help that might or might not be useful

https://stackoverflow.com/questions/34555765/in-swift-how-to-remove-a-uiview-from-memory-completely
 
You are so far off track that it isn’t funny. If you don’t want to listen to us, fine, do it your way. But if you are pushing viewcontrollers onto a navcontroller and then try to delete them, all you will accomplish is crashing the app. Your link is to UIViews, which are very different than UIViewControllers. You’ve been told repeatedly that you need to use one viewcontroller and simply update its contents, but you refuse to listen.

So good luck.
 
Ok, I’ll entertain your question. Although I don’t have the right answer for you I do know that swift has a deinit method that is called right before a class/object is deallocated.

As a means of checking to see if your views are being dismissed add a deinit method to them. In this methos simply put a print statement that you can use to diagnose and see if your objects are ever even being deallocated.

https://docs.swift.org/swift-book/LanguageGuide/Deinitialization.html

Here’s the swift reference to how deinit() works. Also swift used automatic reference counting (ARC). This means that Swift’s checks if there is something referencing an object. If there is a reference then the object/class won’t be deallocated. If there is nothing referencing it then swift will automatically deallocated it.

https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html


Having this information we can assume that for some reason there exists a reference to your previous views. I have a hunch that this is happening because you are literally pushing views on top of each other. Meaning the previous view owns the currently displayed view, thus you can’t deallocate any of the views in the stack or else you will crash your app.

Please please, read the books and references you have been given. The people here are trying to help you. We are not your enemy.

Also here’s a link that might be helpful in answering your questions.
https://stackoverflow.com/questions/44792583/deallocation-of-viewcontroller
 
  • Like
Reactions: MisterSavage
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.