iOS Multitasking: Reductions performed by system upon entering background - cocoa-touch

I've watched the WWDC 2010 talks about adopting multitasking and I have started enabling our app, however I have a question regarding releasing non-visible views.
According to the talk (Session 105 - Adopting Multitasking on iPhone OS, Part 1 - 00:34:50) it is stated that the system releases "non-visible UIViewController views" when entering the background. However during my testing (in the simulator), I'm not seeing this happen.
The -viewDidUnload methods aren't being called, and after entering the foreground and viewing a previously hidden VC, the -loadView method is not being called either. So the hidden VC views in my UITabBarController aren't being released at all, contrary to what they said in the talk. Any ideas?
There's no mention of this in the "Moving to the Background" documentation, only in the talk.
Any clarification would be greatly appreciated.

Have you tried simulating a memory warning while your app is in the background? I believe that the views are only released when other apps start requesting memory. If memory consumption stays the same, your views are not released so that you can switch back quicker.

Related

applicationWillTerminate not getting called on force quit of iOS app

Does anyone have any insights into when/under what conditions applicationWillTerminate is called in iOS 5/6?
I've got some logic i'd like to execute whenever the application terminates (not moves to the background), for example if the user navigates to the application bar at the bottom of the screen by double tapping the home button and force quits the app.
when i try to do this on a test device, applicationWillTerminate does not seem to get called. Is there a reason for this?
My plan B is to tie that logic to some persistent object like a singleton or a static that is automatically destroyed when the app quits.
Any suggestions?
thanks
Have you read the documentation for applicationWillTerminate:,
It says,
For applications that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the application. For applications that support background execution, this method is generally not called when the user quits the application because the application simply moves to the background in that case. However, this method may be called in situations where the application is running in the background (not suspended) and the system needs to terminate it for some reason.
There is a "maybe" mentioned there. Probably that answers your question. So it is not necessary that this will get called when you quit the app. Probably you might have to use UIApplicationExitsOnSuspend to disable multitasking and then it might get called while putting in background. But that again depends on your app requirement. If you cannot disable multitasking, you might have consider doing that in applicationDidEnterBackground method or so. I am not sure if there are any other delegate methods which will help in identifying the force quit.

Application crashes while logging out in iPAD

My question is specific to iPAD, and I also aware of the basic memory management of iOS, but I am having a different problem.
As I have build an application where I have several UIViewControllers and UIViews,
I have a loginController thats gets called when I launch the App.
My MainView is a single screen with all the ViewController loaded and placed at their respective places and the app runs fine and smoothly.
Problem:
Problem comes when I logout, most of the time my App crashes by saying EXC_BAD on the
[super dealloc] line of my mainView controller.
As for now on I have added a custom function cleanUP in all my viewControllers that gets called when user logout from the app.
Is this the right approach ?
As I know that we can clean up in our didload etc. function and the dealloc gets called too.
but here i have an iPAD when my all viewControllers are just open in front of me, They will be closed or not visible when I logout from the App.
So how to approach on my crash issue and How to manage memory here in my iPAD?
The best way I know to resolve bad-access problems is to use Instruments with the Zombie tool. As you probably know, when you get a bad access issue, is because you try to access to an object that is deallocated.
Try go to Product -> Profile and choose Zombie. Hit record and reproduce your crash. then inspect the pointer to the object that produced that crash and look for the retain count.

Does iOS use some mechanism for caching/restoring UIImageView objects?

I'm using a lot of small images that are placed into UIImageView objects. Currently, I'm trying to foresee the problems that might occur later, such as memory warnings, staying in background and etc. My app is quite small - less than 10Mb but still, I'm a little bit concerned. The reason is that I'm not sure how my app will cope with the situation when a lot of UIImageViews are loaded on screen, then app goes to background, and then after a long time comes back. Do I have to reload all on-screen UIImageViews?
I have read that iOS will cope with UIKit data (such as image views) itself when backgrounded. And that I do not need to worry about restoring this though. It would be OK if my UIImageView objects would use PNG image files directly from app directory. But the thing is I'm using spritesheets (files with several images packed inside), then pulling those images with CGImageCreateWithImageInRect, and then passing to UIImageView at some time point. Now, I'm questioning myself, will iOS cache my on-screen UIImageView objects, or do I have manually to reload those UIImageViews when app goes active? I understand that if a lot of apps will be running in background then my backgrounded app might be killed. But I'm worried about the situation when my app will be still alive (in background) but with released UIImageView objects...Please share you knowledge and insights :)
Current implementation of "background" apps do a complete snapshot of your app memory. Such approach guarantees that app will be restored after complete killing from a memory in unchanged state. This mean that you do not need to do any additional manipulations such as persisting of code-generated images etc to support restoring of the app. UIImageView will not be unloaded automagically if you will not implement a clean-up logic inside of applicationDidReceiveMemoryWarning for UIApplicationDelegate instance. However an auto clean-up logic implemented for cached UIImages loaded thru imageNamed method.

iOS 3 - UITabBarItems disappear from UITabBar after a memory warning occurs

At a great number of requests from people using older iOS hardware, I'm currently refactoring and optimizing my app so it will work on iOS 3. That being said I've got a glitch with my UITabBar that I can replicate on all of the iPhone 3G units I've tested it on.
The glitch appears to have been fixed in iOS 4, but I was wondering if before that time, anyone else had this glitch as well and had figured out a (relatively elegant) workaround for it.
The problem is what you can see below; when a memory warning occurs and all of the views offscreen are released, when I bring a view controller with a tab bar back on screen, all of the UITabBarItems that are supposed to be in it are gone. As far as I can see, they're not being drawn at all; ie tapping the tab bar has no effect. After setting breakpoints and examining the UITabBar and its items in memory, they're all still there (ie not getting released), just that they're not getting redrawn when the UITabBar is re-created in the controller loadView method.
My app works similar to the official Twitter app in that I implemented my own version of UITabBarController so I could control the integration of it with a parent UINavigationController properly. I set it up as closely as possible to the original UITabBarController class though, with all of the child view controllers handling their own respective UITabBarItems and initializing them inside the class' init methods. Once the child view controllers are passed to my TabController object via an accessor method, the tabBarItems are accessed and added to the UITabBar view.
Has anyone seen this behaviour before and know of a way I can fix it? I'm hoping there's a really simple fix for this since it already works in iOS 4, so I don't want to hack it up too badly.
Thanks a lot!
After a bit of research, I think I found a solution to this. It's not the most elegant solution I was after, but it definitely works.
I'm guessing after a memory warning is triggered, something is happening to the UITabBarItem objects that basically renders them corrupt. I tried a lot of things (flushing out the UITabBar, re-creating the controllers array etc), but nothing worked.
I finally discovered that if you completely destroy the UITabBarItems and allocate new ones in their place, then those ones will work. :)
So my final solution to this was to add an extra condition in the viewDidLoad method of my controller that if the detected system was iOS 3, and there was already an array of UITabBarItems, it would go through each one, copy out all of the properties needed, destroy it, allocate a new one and then copy the old properties over to the new one.
I'm still going to keep an eye out for a better solution (I think there's a bit of overhead in this method), but thankfully at this stage, iOS 3 legacy support is becoming less and less of an issue. :)

Problem: restarting App

My App is a view-based application. At the beginning I show my logo and after a delay of a few seconds it changes into another view. from then on the user can switch to a lot of different views.
Sooooo.. My Problem: The thing is, when I restart my App. [..well closing and reopen by touching the icon..] the app itself doesnt restart in the sence of jumping to the very first view. to the contrary: at restart the user just returns to the last view that was open.
So I dont know why this is.
Is it normal to somehow manually tell the app to return to the very first view after restart? And if so, how do I have to do that?
PS.
I have so no idea what to do.. Maybe my problem has to do with the timer i used in the first view to change after a delay of time?
Please, is there anyone, who can help me?
Your problem is that, as of iPhone 4, returning to the home screen does not terminate your app. It's just made inactive, so opening it again reactivates it. In most cases, this is a good thing. If it doesn't work for your app, you can add the UIApplicationExitsOnSuspend key to your Info.plist with a value of YES.
(As I said, you should only do this if it really helps usability. If it's just about getting your splash screen shown again, most users and possibly Apple will frown upon it.)
iOS 4.0 and greater have a fast-start thing that allows apps to restart back from where they were upon restarting. There are several ways to deal with this:
1.) your App Delegate receives info about being but into the background and resumed. - (void)applicationDidBecomeActive:(UIApplication *)application and - (void)applicationDidEnterBackground:(UIApplication *)application are the relevant functions here. Check the docs.
2.) You can also disable the background, inactive state completely by including UIApplicationExitsOnSuspend in you Info.plist as Chuck already pointed out.
Overall, you should check the application state docs on Apple's Side.