Iam having a very basic doubt in memory management. If suppose iam allocating memory for an object in viewWillAppear method. Should i release the object in viewWillDisappear method or in the release all the objects in the de
It's dependent when you want to release the object. You don't have to release on viewWillDisappear. But, you can, just think about when you need it and when you don't. Technically, either one is fine. Depending on the situation though I would think: if you need the object for multiple views don't dealloc in viewWillDisappear, if you need it only for that view and you don't need it again, dealloc in viewWillDisappear.
Here's a very easy to learn tutorial on objective-c memory management.
http://cocoadevcentral.com/d/learn_objectivec/
You'll learn a lot about retaining and releasing variables. In general variables are defined according to scope (i.e where they will be used) For example, you may want to initialize a variable that's used throughout a class in viewDidLoad and release it in dealloc. It all depends on where you need to store data and for how long.
Related
HI,
I am working on optimizing my iphone project for proper memory management.
my question is:
what's the difference between releasing an object inside dealloc or releasing in the same method where we init it?
Thanks!
Generally, you want to release an object as close to the point in the code where you initialize it as possible. If you have local variables in a method that you are init-ing, you release them before the method returns.
This, however, is not possible with instance variables, since they stick around with the objects; thus, you release them in a dealloc method.
I'm developing an iPhone application, and I very new on iPhone development.
I've created some custom classes with instance variables (NSArray, NSString, etc.). All classes inherits from NSObject.
Should I create a dealloc method to release all instance variables?
Thank you.
Yes, you definitely need a dealloc if you are keeping instance variables that are objects. You will also probably need to retain or copy those as well, depending on how your object creates/uses them.
Check out this article on memory management. I think it explains it pretty well. You must also read the Memory Management Programming Guide for Cocoa. Even if you don't fully understand everything, read the whole thing through, then read the article, then do some work, get some crashes and read it again :) eventually it should all click.
In iPhone development its pretty much SOP to have a dealloc since there is no garbage collection.
You have to release any object your class has ownership for. That means, yes you have to overwrite the dealloc method and release the objects there.
Normally you have ownership over values (objects) in instance variables, but it also depends own how you create them.
You should definitely read the Memory Management Programming Guide, it describes pretty well when you gain ownership.
Yes, having a dealloc method is normally the best way.
If you want to reclaim memory used by your instance variables you will have to release them when you are done with them. You could add a method to do this clean up:-
- (void)cleanUp {
[myArray release];
[myString release];
}
Call it when you no longer need the instances.
Now, the chances are that the point in time when you want to release these variables is the point in time when their parent object is destroyed (parent object is gone, so instance variables are no longer needed). As -dealloc is automatically called for you when the parent object is going to be destroyed - it makes more sense to put the cleanup code in dealloc than in our -cleanup method that we have to call at the right time.
If you don't want to reuse the memory, eg. if you are never going to be finished with the instance variables, then you don't need to release them and might not need a -dealloc.
I found that the iphone have viewDidUnload, and dealloc. I want to release the object. Which method should I use to release the object? What's the different between them?
Send release or autorelease to release an object. You shouldn't send dealloc; the Obj-C runtime will do that.
If you're asking where you should release an owned object, read: "When should I release objects in -(void)viewDidUnload rather than in -dealloc?"
Do not call dealloc. Use the retain-release model for memory management, and Objective-C will take care of deallocating memory for you.
See this link for a good explanation of how retain-release works.
The difference is that viewDidUnload is used to release "spare" objects in low memory situations while dealloc is used to release all objects when the view is no longer needed.
This means that you will almost always have a dealloc method but have a viewDidUnload method only where it makes sense.
I have an instance variable *TangramLevel(:UIView) currentLevel; in my viewController class, and I have an instance allocated at start (it's retainCount 1). I attached it to the view [self.view addSubview:currentLevel]; (retainCount 2).
When the level finishes, it notifies the controller, so controller removes it from the view [currentLevel removeFromSuperview]; (retainCount 1), and release the allocated instance - [currentLevel release]; -, to have it deallocated (retainCount 0 = invoke dealloc).
Then on the next line, controller wants to allocate/addSubview a new level instance with another level data, but the application crashes (EXEC BAD ACCESS).
If I don't release currentLevel after removeFromSuperview, the appliaction works, but I have an unused level instance left in memory then, which is also a problem (the main problem itself).
Is there any bug in the method I wrote above? Or the bug is elsewhere, maybe in the level class? I allocated some UIImageView in the level, but I release every allocated object in the levels dealloc method. Any ideas?
Post your code.
This is definitely a memory management issue. The question is "where is the problem created?" To answer that, we need to examine the following:
Your "currentLevel" iVar handling code (do you used synthesized properties, etc.). Post it.
How are you assigning the view to currentLevel?
Where are you releasing this, specifically?
How is your view's dealloc implemented (what do you release and how)?
Is there any other code that retains/releases this view or anything related to it?
The fact that you're calling release in your "I'm done with this level, let's swap in the next" code suggests an overall design issue. Make the memory management of each of a class's iVars the responsibility of its accessors and ONLY use the accessors to interact with it (even from within the class/instance). With synthesized properties, this makes it brain-dead-simple. That way you don't have to worry about where to retain/release iVars because it's always funneled through the accessors.
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