RetainingAndReleasing are the procedures for managing an object's RetainCount; understanding the way they work is crucial to making sure your application uses proper MemoryManagement. Several specific examples are outlined in RetainReleaseTips.
In Java you're free to create as many objects as you like and simply drop all references on them when you're done with them. The GarbageCollection system will notice and sooner or later come to clean up the data you've left behind. ObjC is more strict about MemoryManagement than Java. This means that you have to take a little more responsibility for your objects.
Every object has a RetainCount that goes up by one when the object gets a
It goes down by one when the object gets a
When the RetainCount reaches 0, the object will call
[self dealloc], thereby releasing the object's memory.
I can tell the system that I need AnObject by sending it a
retain message. If I do, I must send it a
release message when I don't need it anymore.
When I create AnObject with the
alloc method, I'm implicitly sending that object a
retain message. That means it has a RetainCount of 1.
I am held responsible for sending it a
release message when I no longer need the object, and everyone else will assume that I do so.
That's part of the Social Contract of Cocoa. When I do, the RetainCount will become 0 and sooner or later the GarbageCollection will come to get the thing.
Since you have no prior knowledge of, and more importantly, no control over the lifetime that AnObject
has by virtue of its creation in My_Class, you claim control by sending it a
retain message, and its RetainCount becomes 2.
When you later send AnObject a
release message (because you are done with it and want to let the system know you no longer need it)
AnObject will not necessarily be deallocated! Your
release message simply decreases the RetainCount by 1.
If My_Class was not finished with AnObject, it would still have a RetainCount of 1 because I would not have sent it my own
and AnObject will not be deallocated.
Likewise, if I should send MY
release message to AnObject before YOU are done with it, I would still only decrease the
retain count by 1.
If you are still using the object, your own retention of AnObject should suffice to leave it usable to you until you are done with it.
Simply put: An object is ONLY deallocated when it has received equal numbers of
release messages, thus zeroing its RetainCount.
Scenario 3: You can also choose to AutoRelease an object:
If you create an object within a method, you typically will want to dispose of it within the scope of that method (see bookkeeping remarks below).
However, if you also want to
return the object from that method you are faced with what is referred to in topic AutoRelease as a "conundrum".
If you just
release the object before you
return from the method, the object pointer that is returned will be garbage.
return from the method before you
release the object, that
release message will never
be sent to the object, and will at best cause you bookkeeping problems if you try to balance it with a
release message someplace else,
and will cause MemoryLeaks if you don't deal with it at all.
To make it possible to
release objects you're
returning, the AutoReleasePool was introduced.
The technical niceties of AutoReleasePool are fairly complicated, but from the programmer's perspective, it looks like this:
When you send an object the
autorelease message, it is added to the local AutoReleasePool (technically, the most recently-created
one in the current thread, discussed in more detail under AutoReleasePool).
At some point (not specified, but currently the next iteration of the RunLoop) the AutoReleasePool in which that object is listed will be destroyed and all the objects in it get a
Other methods thus have time to
retain the object if they still need it.
Most methods that
return objects use AutoRelease,
so if you get an object back from such a method, you should generally
retain it if you want to keep it.
autorelease message should not be used casually where a
release message is more appropriate.
Keep in mind that the AutoRelease machinery adds some
overhead, and could impose a performance penalty in extreme circumstances (e.g., a tight loop that creates thousands of
Sample code dealing with specific what-ifs can be found in the topic RetainReleaseTips.
There you can also read about nasty things called RetainCycles and hints on how to avoid them. In MultiThreading apps RetainCycles can be a real headache, so if you're that far along, see the topic of WeakReferences that Ken Case from TheOmniGroup came up with.