Let's say i have a navigation controller in my app delegate.
Why is it necessary to release it on dealloc method in my appDelegate?
When the dealloc method of my appDelegate is called, it means user is exiting the app, so the leak doesn't affect my application.
So why would i release anything in dealloc method of my appDelegate?
It's not necessary. Might even be cheaper to skip it and just let the OS free up the process.
Unless any objects of yours do anything useful in their dealloc, like saving data.
It's good practice :)
Related
There are a few instances where my app crashes when turned back on from sleep and the app is still open. It happens if a UITableViews is open when the iPhone is put into sleep; the table is being filled from an XML being parsed. I understand why it is crashing; in my viewDidUnload method I am releasing the array that is filling the table. How to handle this I am not sure; yes I could simply not release it in viewDidUnload, but then it would never leave memory if you returned to the main menu.
Any help would be appreciated!
The method viewDidUnload is not the right place to release your data if at all. I quote Apple's documentation, which desribes it better than I could:
This method is called as a counterpart
to the viewDidLoad method. It is
called during low-memory conditions
when the view controller needs to
release its view and any objects
associated with that view to free up
memory. Because view controllers often
store references to views and other
view-related objects, you should use
this method to relinquish ownership in
those objects so that the memory for
them can be reclaimed. You should do
this only for objects that you can
easily recreate later, either in your
viewDidLoad method or from other parts
of your application. You should not
use this method to release user data
or any other information that cannot
be easily recreated.
ViewDidUnload is used only to release view related objects. A view controller can release its view because its not shown, still your instance of that controller exists and so does your model.
I want to release objects in my programming based on UITabBarControllers, all tab bar items launches together at once,
so what should I do for this??
Just release all what you retained. I think dealloc will be called when necessary.
Maybe this will help you a bit:
Dealloc not called for ViewController; it's about why dealloc is not called when using UITabBarCtrlr.
You can still release anything that you retained, you don't have to do it in dealloc. Just recycle anything anywhere that you want to, and set the object to nil. In dealloc, don't release anything that is nil so you are safe. However, your UITabBarController might still assume the validity of the objects, so it's up to you for implementing the logic.
If possible, you should just allocate a new UITabBarController.
Should I implement dealloc in my app delegate and release my ivars there? As I understand it, when an app gets terminated, all the memory associated with it gets freed automatically. So basically, there's no need to release any ivars yourself at termination.
I've found this question here already: Does it make any sense to release ivars in appdelegate's dealloc?
One of the answers says that objects might have clean up code in dealloc, so you might want to release ivars yourself at termination. But when I put an NSLog in the dealloc of my app delegate, it's never called. My assumption is there's no use at all for it so I don't even have to implement it, am I right?
It may be necessary in future iOS releases. For the sake of forward compatibility, and since Apple seems to recommend it I would release those ivars.
You are right, you don't need to release your ivars in dealloc (The example templates that come with the SDK do have a -dealloc though). The OS will reclaim any memory associated with you app. If anything, it will just add a small amount of overhead. Also, as far as I know, there isn't any guarantee by the environment that the -dealloc in your app delegate will ever get called, so it may never even execute.
Aren't these methods called when the app is about to be shut down? If so, then won't the memory be all cleared out anyway?
If you only have one view that lasts the duration of the app, then unload and dealloc are currently never even called, so these methods are actually unused and unneeded.
However, if you ever expand this app to have views and objects that get switched in and out of use, then in low memory circumstances these methods may well be called to lower your app's memory footprint so that the app doesn't get killed for using too much memory. So leaving them in (and coding them correctly to release internally allocated objects and malloc'd memory) for future code reuse is considered good practice. That's why they come with the various Cocoa templates.
Aren't these methods called when the app is about to be shut down? If so, then won't the memory be all cleared out anyway?
It is true that viewDidUnload and dealloc are called when an app terminates, but these are certainly not the only times. It is very important to correctly implement these cleanup methods, as well as didReceiveMemoryWarning.
If you don't clean up properly in dealloc, then your app will start to leak memory. Over time, it may consume more and more memory, until it gets terminated by the system.
Similarly, if your viewDidUnload doesn't release its resources, you can be leaking memory. If the view is used multiple times, each invocation will leak.
Careful memory management is more important than ever with iOS 4, as your application may end up in the background if the user presses the Home button. This means it may run for longer than ever, and thus you will be reusing the same view controllers when it regains the foreground. If your app doesn't release unused memory properly, it will almost certainly be killed by the system.
iOS Memory Management Programming Guide
viewDidUnload is only called in low memory situations. You want to release all object you create in viewDidLoad. You want to pair them up. You still want to release everything in dealloc, since viewDidUnload will not be called if low memory situations never occur in your app.
Keep in mind that each class inerithing from NSObject has its dealloc and so when the reference count of an object reaches 0 , its dealloc is being called, meaning that the memory owned by that object would better be deallocated.
Similarly viewDidUnload is a method that each UIViewController has and it is being called when the main view associated to the controller is no more needed, no more visible if you want (you can think of it being called when you a pop the controller from a navigation stack or switch a tab in tabbar controller). It is convenient for the app and the iPhone/iPod not to have the objects owned by the view around when the view is not displayed/active/used etc.
Finally the AppDelegate, as an object has its own dealloc method, so maybe your confusion can come from this point.
Right now, I do most of my cleanup work in dealloc (cleaning up IBOutlets, allocated objects, etc.). What other places should I do cleanup work in order for my app to be a well-behaved one? Could you explain the things that are typically done in those methods as well?
For example, viewDidUnload, applicationWillResignActive, etc.
For views, I typically release any UI widgets that were created from the NIB file in viewDidUnload. Any models or other objects I clean up in the viewController's dealloc.
Sometimes I have views that create a model (say a Dictionary of section names to section rows) from a primary data object. If I create/build an object in viewDidLoad I will release it in viewDidUnload (since my viewDidLoad will get called again when the time is right).
I believe that in SDK 3+ you don't have to typically worry about implementing didReceiveMemoryWarning directly as the new viewDidUnload method is the main place to do your view cleanup.
For normal objects (objects without special life cycles like a view controller has) I just release their member vars in the dealloc.
Don't forget:
- (void)didReceiveMemoryWarning
Note: This "Answer" is only relevant to app quit/termination.
According to the answer I received to my question, it's not even necessary at all to do cleanup work like cleaning up IBOutlets, allocated objects, etc. Just save state (as necessary) when your app quits, and let the iPhone OS handle the final cleanup.
Note that your question is ill-formed. The -dealloc method of UIApplication is never called. The -dealloc of your application's delegate is never called. That means that any objects that are retained by your application's delegate will never be released, so their dealloc is never called.
You should be doing your cleanup in your application delegate's applicationWillTerminate:
Since your application is about to die, you don't really need to do anything except give back non-memory resources, make sure your data files are properly closed, and that your NSUserDefaults are synchronized so you can restart properly the next time you are run.
However, any object that might be allocated and deallocated repeatedly over the life of the program deserves a proper Obj-C dealloc method, as documented by Apple, and it is good practice to write this for all your classes, even though they won't be called, just so you build good habits, and readers won't be confused. Also, it saves maintenance headaches in the future, when you DO create and destroy multiple of these, for example in your unit tests.
I would use the [yourObject release] method, but replace yourObject with an object