Strange Behaviour of tabbarcontroller - iphone

I have a tab bar application and i am encountering a strange behaviour....when i toggle the tab bar and reaches into new view controllers sometimes the viewDidLoad of these view controllers are getting called...though viewDidLoad should get called only first time...
can anyone tell...any suggestion??

If there's a low memory warning then a tab bar controller will release all views that are not visible. This means that you can get viewDidLoad called more than once because the view has been unloaded.

Is your app memory-intensive, perhaps to the point that you're receiving memory warning? Though I have not experienced the behavior you're describing, it's possible that due to heavy memory use your unseen views are being released due to a lack of memory. When they're next called into view they would need to be reinitialized, calling viewDidLoad.

Are you sure it's viewDidLoad, not viewWillAppear?
viewDidLoad will only be called once in each UIViewController subclass, so if your layout is like this:
-UITabBarController:
- HappyUIViewController
- SadUIViewController
- ThirdUIViewController
Then viewDidLoad will be called three times. Once for HappyUIViewController, once for SadUiViewController, and so on.

Related

why only viewWillAppear called on navigation back

I have doubt need to be clear.. I have stack and a navigation controller.now when the stack loads the viewDidLoad viewWillAppear viewDidAppear will be called. when i click some button then this button push me to the new stack , now new stack gives me the option of the back..now when i click on the back of the navigation controller..why only viewWillAppear will be called ..why not viewDidLoad and not viewDidAppear
Stack is Last In First Out (LIFO), so when you push new view controllers to the stack, previous viewcontroller will not get destroyed( and they remain in memory). When you pop back, there is no need to recreate the Viewcontroller since it is already in memory. So only viewWillAppear gets called.
As to why viewDidAppear doesn't get called in this case, I cant remember where I have read this, but viewDidAppear gets called after your UIViewController's view was added to the application's UIWindow heirarchy. And this process is done before the UIViewController is shown for the first time.
viewDidLoad only called when viewControllers views are loaded into the memory. It will be done when
the first time the view is needed to be shown
sometimes when viewController needed to be reloaded again, because
it is purged from memory for some low memory reason.
In your case, when you pop back, the viewController is already loaded, so no need to call viewDidLoad again.
Full life cycle of ios ui explain here.
http://www.verydemo.com/demo_c134_i4568.html
Note By Abizern from comment: this is true for iOS5 and earlier. iOS6 does not unload views anymore.
First of all, nice question #user2102546. Checkout here the perfect reason for your query.
viewDidLoad only gets called if view controller's views were unloaded, and need to be reloaded.
Normally, if you use a navigation controller, and go back to a previous view with one of the pop methods, viewDidLoad does not get called again, because the view are not unloaded yet.
However, the system can unload the views of any view controller when it is not frontmost in order to free up memory, so viewDidLoad can get called any time a view controller is about to be presented. You need to write your code to respond correctly to the different events.
Enjoy Programming!!
I don't have a complete answer for you but I hope this helps.
viewDidLoad is a callback for modifying a view after the load event has happened. In your case, the view has already loaded. The fact that it is not in view doesn't mean it has been unloaded from memory.
viewDidAppear: While I don't know why this event isn't firing and would be happy if someone else would fill in the gap.

How to unload view of UIViewController

I have custom control like tabbar which displays many controllers some of them also have my tabbar with other controllers, so, my app uses lots of memory because every controller is stored in memory. So I want to unload invisible controller, but I not found any method for unloading UIViewController. How can I do it?
PS. I can not use UITabBarController, really can't.
You don't. UIViewControllers don't get unloaded in low memory, just their views do.
This happens in didReceiveMemoryWarning on your own view controllers and gets called automatically when a low memory warning occurs.
Override this and unload anything that can be re-created in viewDidLoad.
Remove the view controllers view from it's superview and release the controller. Job done.
I know it's an old thread but might be usefull for someone.
You can unload viewControllers view by calling:
[viewControllerWhoseViewYouWantToUnload didReceiveMemoryWarning];

could strange UINavigationController nav bar behavior be due to memory leaks?

I'm getting strange navigation bar behaviour, for example when I hit back button the screen displayed is the previous screen, however the Navigation Bar items do change. So I'm left with screen A, but with nav bar buttons for screen B.
Could this be due to memory leaks? I do note with my app still:
This behavior seems to happen:
immediately if I trigger memory
warning via the simulator menu, or
on a device after it has been on
for a while [without being killed
and then restarted as an app].
I do have some memory leaks I'm
trying to clean up (i.e. Profiler
highlights items in "leaked blocks"
section)
Any tips on fault finding root cause of why pushing a back button would end up in a weird state? e.g. screen on previous parent view, but nav bar items don't change...
UPDATE - I have finally removed the memory leaks in my app, however I note the nav bar issue still remains. I guess this doesn't confirm the answer to my question is NO in general, but in my specific case it wasn't the memork leak...
From Apple:
The navigation controller updates the
navigation bar each time the top view
controller changes. Thus, these
changes occur each time a view
controller is pushed onto the stack or
popped from it. When you animate a
push or pop operation, the navigation
controller similarly animates the
change in navigation bar content.
Based on this, I would start by looking for a bug or misconfiguration in your view definitions. Check for any InterfaceBuilder warnings if you defined your views via NIBs. Make sure your view hierarchies are correct in both UIViewControllers. Also check for possible bugs in your view life-cycle methods: viewWillAppear:, viewWillDisappear:, etc,.
Actually, it would be nice if you could post some screenshots and/or code. Thanks!
Any view that is not currently visible and only retained by it's view controller (as a part of the view property of that view controller) will be released (along with any non retained subviews) when a memory warning occurs.
Chances are you are creating the view as a part of init, and not retaining it in the controller (simply letting the view socket hold it from releasing). One way around this is to create properties for the views you create (nonatomic, retain), and after creating them and autoreleasing, assign to those properties, don't forget to assign those properties to nil as a part of dealloc to avoid leaking. Another way is to create your custom view elements in viewDidLoad as opposed to init.
Hard to say without code example from the offending views :)
I've seen something like this happen after calling -[UINavigationController setViewControllers:]. You might try not doing any programatic manipulation of the navigation controller's view controller beyond calling -[UINavigationController pushViewController:animated:].

viewDidUnload is not called for some view controller

I have a UITabBar with 2 view controller. The first one shows a UITableView, second one shows a UITextView.
When I click the first tab to show the tabview, and issue the memory warning in the simulator, the UITextView's didReceiveMemoryWarning is called automatically, however, the viewDidUnload is not getting called.
When I tap the second tab to show the textview, and issue the memory warning in the simulator, the first view controller's didReceiveMemoryWarning is called automatically, and the viewDidUnload is called as well.
So I want to know why the second view controller's viewDidUnload method is not called. Also, how can I make the first view controller(the one shows table view) viewDidUnload method is not called automatically when the app receive memory warning message.
Thanks.
Apple documentation implies that automatic view unloading only happens when the view was loaded from a named NIB file. If the UITextView view was created manually that would explain the unloading.
As to the second part, from what I've tried, there is no way to prevent the automatic unloading as it happens in the base class. If there is a way to create the view and "hide" the fact it came from a NIB, that might do it.

Presenting a ViewController

Does presenting a ViewController cause the presented controller to run its viewDidLoad method?
If a view1 is loaded and another is presented. Then something triggers to present view1. Will it run through its viewDidLoad method?
IF not how should this be done? ViewDidAppear?
Building on what Jesse relayed, the viewDidLoad is called when the view is loaded into memory (usually the first time the view controller is ever about to be presented since app launch - simplified, but this will suffice for now).
When you display other view controllers and then come back some how to this original "view1" view controller, unless there was a memory event that jettisoned it from memory, it will NOT call viewDidLoad again.
Instead, it will call the following, in order:
viewWillAppear:
viewDidAppear:
In viewWillAppear:, you have a place to do things "off screen" before your view controller is displayed.
In viewDidAppear:, you can do additional operations that are appropriate for when the view controller's view is already visible. For example, you want to run some little animation that the user will see once the view controller is fully visible.
In both of these methods, make sure you call super's implementation before you do anything. Also, to learn about this lifecycle, set a breakpoint or NSLog() statement in each of these methods (viewDidLoad, viewWillAppear, viewDidAppear) to see when they are called.
There's a concept piece in the Apple docs on View Controllers that is worth the 20 minute read - it'll clear up a lot of this key life cycle information about View Controllers, and these are central to iOS development. See the section "Understanding the View Management LifeCycle" at:
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html%23//apple_ref/doc/uid/TP40007457-CH101-SW1
viewDidLoad is only called when the view is loaded into memory. Usually the first time it appears (could be more often if there are memory dumps and etc).
viewDidAppear: is called every time the viewController's view becomes the 'active' view in the window.