I am having a doubt regarding the behaviour of dealloc in ARC in Nav bar applications.I have a nav bar application in which 5 screens are there.I am pushing the view controllers in the navigation stack and has written the dealloc function in respective VC where i am releasing the strong reference variables.Dealloc's are called many times but the memory footprint is still going up.IS the VC de-alloced only when he is popped from the navigation stack or it would be called after some time in the stack.
I don't have the back button in the navigation bar for the user as it is not necessary.So should I manually remove the VCs from the navigation stack or they would be deallocated by ARC by its own?Any help would be appreciated as I am really stuck up with app crash issue.
UINavigationController manages its view controllers' memory by itself.
If your memory footprint is increasing, that must be due to some other memory leak.
Related
Consider this code to push a new controller onto the nav stack:
AlphaColorController * a = [[AlphaColorController alloc] initWithColor:color name:name alpha:0.25];
[[self navigationController] pushViewController:a animated:YES];
[a release];
There is no pointer kept for a. If a user navigates into this new controller, then navigates "back", and then "forward" again, is the nav controller smart enough to know this controller is already there, or if it isn't, to allocate it again? How necessary is it to first test (using a pointer) if the controller has been instantiated yet before pushing it multiple times?
UPDATE: putting it another way, will this code effectively re-allocate the controller every single time the user navigates into that particular area of the nav controller? the nav controller is going to rereate and push the newly created controller every time?
I don't think you understand how your code is operating. You are, in fact, creating the new view controller object you speak of, and you are, in fact, pushing it onto the nav stack. And what do you mean not keeping a pointer to it? That little star ain't there for nothin'!
NavigationControllers keep a reference to their navigation stacks until such a time as a view is popped off the stack. In which case, said view is deallocated and destroyed.
When a navigation controller push a view controller, the pointer of the view controller will be added into the stack of the navigation controller. So the retain counter +1
The the navigation controller keeps all references of the view controllers it pushed.
I have a tab bar application. Each tab contains navigation controller allowing the user to transition from one view to the other. Each view is being handled by a view controller and each view controller class has -didReceiveMemoryWarning method.
Problem: When I use "Hardware > Simulate Memory Warning" option of iPhone Simulator in any model viewcontroller after after that if I want to dismiss that controller using -
[self dismissModalViewControllerAnimated:YES]
Then, viewDidLoad method is not called for the controller to which I have added that model view controller, and app crashes there.
Any idea, what I'm doing wrong.
Probably this will be because, in viewDidLoad method u r not taking care of all the released object.In simulate memory warning , we have to release all those object , which can be loaded in viewDidLoad.
I have a tabbed application with navigation controllers in tabs and view controller in them. When I press some tab item and go deep inside view controller hierarchy (that is maintained by navigation controller), what happens when I press tab item directly? IMHO all the view controller are on stack in memory and if I start navigating again from the the first view controller deep then I'm putting a copies of view controller on navigation stack. How should I do proper memory management? IMHO i need to release (pop) all view controller that are on screen (EXCEPT the first one) when user click some tab item. How to achieve that?
The system will take care of unloading un-needed views when it needs memory (and reloading them when they are needed), so if you have implemented the viewDidUnload and receivedMemoryWarning method correctly, you should be fine. The view controllers themselves take hardly any memory (unless you've allocated tons of stuff yourself). In any case they are not allocated on the stack, as objects they are allocated on the heap (general objective c rule of thumb). When you push a view controller it is retained, when you pop a view controller it is released. Usually you wouldn't expect the navigation controller in each tab to pop back to root because you pressed another tab, but if you really want to do that then you can use popToRootViewController method.
I have a main view controller with two other view controllers as member variables, representing different "tabs" within the main view. They are hidden and shown when the "tabs" are tapped. All of these are in a nib file.
When I get a memory warning, viewdidunload is called and the view is dumped, as expected. However, they are never recreated and viewdidunload is never called again. The main view controller is attached to a nav controller.
What gives?
When a memory warning occurs, the system may unloads views of view controller that are not visible on screen at that time. The action which triggers the reloading of those view controller's views is something actually trying to access those views. In other words, when some code is executed which accesses viewController.view, if that view had been unloaded, it is reloaded.
In practical terms, this means that your unloaded views will usually be automatically reloaded at the point where they would be shown again. So after a memory warning, change the current view using your tab controller variant, and you should see that it is reloaded (if it was indeed unloaded).
I solved this by dumping and reloading the associated view controllers on a memory warning, but the original cause remains a mystery.
Viewdidappear is never called on the views either, I suspect this is related to whatever the explanation is.
If you're doing view controller containment you have to manage the appearance and disappearance of your view controllers at all time.
When a view controller unloads its the view whole hierarchy of that view is destroyed and is, of course, not saved. When the view of that parent is reloaded, the -loadView and -viewDidLoad code are executed as well as the appearance methods. These methods will not do more than what you tell them to do. If you do not rebuild the view hierarchy of your children in viewDidLoad don't expect them to reappear magically.
The job of the container controller is to load the view of its children (the ones that are visible) and layout them in its own view.
I have an iPad app that has linear navigation with a Navigation Controller. I am pushing View Controllers one at a time with gestures. I also have a PopOverController menu that can push View Controllers. Trouble is, when I push more than 20 it crashes.
Do I have to manually remove View Controllers from the stack after I get above a certain number? I was under the impression that the Navigation Controller would remove hidden View Controllers automatically.
Many thanks in advance.
If you're allocating too much memory use the viewDidUnload to release objects you won't use while the view is not presented again. You can restore then in the viewDidLoad as well.
Try releasing all the controllers after you push them onto the stack and also try releasing the navigation controller. Hope this helps