There is no "one size fits all", exact answer to this question - the implementation of saving application state will depending greatly on the structure of the application so much so that any single solution is unlikely to fit your specific case.
There are some general tips and pointers, however, that should put you on the right road to developing a good state preserving solution:
You will typically want to perform any operations to save state in applicationWillTerminate:
in your app delegate or by listening for UIApplicationWillTerminateNotification
in other classes.
Look at NSUserDefaults. You can use NSUserDefaults to store key/value pairs (similar to an NSDictionary, though you can only store objects that implement NSCoding in NSUserDefaults) relating to preference or other information. Use NSUserDefaults to store state information. One caveat - you shouldn't use NSUserDefaults for storing large amounts of data, as this will slow down your application's launch time (since the values are loaded on launch).
More specific to your case...if all you want to do is preserve the selected tab between application, you should implement applicationWillTerminate:
and use NSUserDefaults to store the selected tab index. Then, in your applicationDidFinishLaunching:
implementation, you'll check for the existence of that NSUserDefaults key and set the UITabBarController's selected index to the stored value if it exists.
If you want to be able to restore, for example, the navigation stack of the selected tab as well, then you'll need to store enough information so that the navigation stack can be accurately reconstructed. What information you should store in NSUserDefaults is hard to quantify in a general sense as it is highly specific to the structure of your application and the possible iterations of view controller hierarchy within the navigation stack.
If you need to restore a more general navigation stack, including possibly entered user data that you don't want to be lost when the application is closed (such as if the user is creating a new record of some kind), I would suggest that you shift your focus away from storing the application state at the app delegate level and instead focus on having your view controller classes listen for UIApplicationWillTerminateNotification
and do their own specific state saving. You would also have to determine some mechanism for using that information saved per view controller on termination to restore the navigation hierarchy. This is a more complex technique that may not be necessary depending on your needs.
Unfortunately this answer is a bit nebulous, especially for the more general and complex cases, because as I noted there is no general solution for this question since it depends so heavily on your application structure.
Here's an example of using NSUserDefaults: http://robertcarlsen.net/2009/06/19/overly-simplistic-saving-state-in-of-for-iphone-847