iPhone SDK: Dealloc vs. Release? - iphone

I am wondering what the difference is between release and dealloc? After reading, the memory management rules (See below)., I am thinking most of the time I will be using release. However, I wanted to know what to do for properties.
#property(retain)....
I have been using dealloc but after reading this article I am not sure that is correct.
You take ownership of an object if you create it using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message. You are responsible for relinquishing ownership of objects you own using release or autorelease. Any other time you receive an object, you must not release it.

You should never call dealloc on anything other than super.
The only time you will be calling dealloc is in the dealloc method of a custom inherited object, and it will be [super dealloc].
When the retain count of an object goes down to zero, dealloc will automatically be called for you, so in order to manage memory properly, you need to call retain and release when appropriate.
If this isn't clear to you or you'd like details about how memory is managed in Cocoa, you should read the Memory Management Programing Guide.

You never call dealloc directly. It is invoked by the system when the retainCount of the object goes to 0. Every time you do a retain, the retainCount is incremented with 1. Every time you do a release, it gets decremented. This way, by balancing your retains and releases, you ensure than when the retainCount gets to 0, dealloc will be automatically called, and your object freed.
As Ben S noted, the only time and place you would call dealloc is in in the dealloc method of an inherited object.

When you use #property(retain) and then #synthesize to generate the property code, you do not need to do any manual memory management on the property. The other answers are correct in that you shouldn't be using dealloc except in your own override of a parent class dealloc.

Related

When does dealloc method call?

I am new to iphone and I want to know when does -(void) dealloc method call. I know it is used to release objects but can we release any kind of object using dealloc method? And is it necessry to add this method and why we write [suped dealloc] in dealooc method?
share your views.
Here is the explanation straight from APPLE's Docs
The NSObject class defines a method, dealloc, that is invoked
automatically when an object has no owners and its memory is
reclaimed—in Cocoa terminology it is “freed” or “deallocated.”.
Important
Never invoke another object’s dealloc method directly.
Here is the answer why we call [super dealloc]?
You must invoke the superclass’s implementation at the end of your
implementation. You should not tie management of system resources to
object lifetimes
When an application terminates, objects may not be sent a dealloc
message. Because the process’s memory is automatically cleared on
exit, it is more efficient simply to allow the operating system to
clean up resources than to invoke all the memory management methods.
You Can release object those which is allocted, copy, or retain by you this is simple to understand. You can not release object those are not allocating by you means autorelease object, which ios detect for no more use in memory ,that time autorelease pool drain that time those object released from memory automatically.
And object dealloc method called when object retain count becomes zero.
You never send a dealloc message directly. Instead, an object’s dealloc method is invoked indirectly through the release NSObject protocol method (if the release message results in the receiver's retain count becoming 0). See Memory Management Programming Guide for more details on the use of these methods.
Subclasses must implement their own versions of dealloc to allow the release of any additional memory consumed by the object—such as dynamically allocated storage for data or object instance variables owned by the deallocated object. After performing the class-specific deallocation, the subclass method should incorporate superclass versions of dealloc through a message to super:
Refer this Link

Dealloc on my custom objective-C

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.

Which method should use to release an object?

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.

Cannot allocate new instance of UIView subclass after deallocating

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.

What sort of cleanup work should I do aside from dealloc in an iPhone app?

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