Previously we learn polymorphism in ObjC : Objective-C : Polymorphism
When an object is allocated, it's counting references is 1. When that count reaches 0, the dealloc method is called, freeing memory; that way, you don't end up with leaks. release decrements with count, while retain increments it.
Objective-C does not use garbage collection. Instead, it uses a reference-counting environment that tracks how many places are using an object. As long as there is at least one reference to the object, the
Objective-C runtime makes sure the object will reside in memory. However, if there are no longer any references to the object, the runtime is allowed to release the object and use the memory for something else. If you try to access an object after it has been released, your program will most likely crash.
Yet, some questions remains unanswered:
- When shoud one use retain ? release ?
- What is a leak ?
- What's the difference between alloc, init, new, copy ?
- How does autorelease works ? Is it safe to use it, and if yes, when ?
First case: you create an object
alloc and init (or anything beginning with init)
copy (or anything containing copy)
NSString * str1 = [[NSString alloc]initWithString:@"foo bar"]];
You're in charge of it's lifecycle. That means at some point you will call release on it, when you're done with it.
Second case: you invoke a method that returns an object
NSString * str2 = [NSString stringWithString:@"bar foo"];
You are not in charge of it's lifecycle. Then calling release on it will cause either EXC_BAD_ACCESS, either a random application crash. Why ? Because you are not the owner of that object, so you can't release it. And since you are not responsible of it's memory management, why would you want to release it ?
So what is retain ?
On scenario 2, you invoke a method that returns an object. Always assume that is object is memory management by the method that just returned it to you. Sometimes, it has autorelease on. So to make sure it's alive for the time you need, you can retain it. For that, you either call retain on it, or you put in a property that has retain on. So now, you own the object. That means you're back to scenario 1 where you should call, at some point, release on it, when you're done with it.
There's an exception : if you add this object to an NSArray, then remember that it will be retained by the array, therefore you forget about it. No release has to be called.
retain should be used when you want to make sure your object will not be released. Actually it's a convention
About this, I recommend the reading of this thread that I started.
What is autorelease ?
autorelease may be used when you are not sure when the object will not be need anymore. This method is not a bad way to do things, but definitely not the only one every time. You may use autorelease when one of your method returns an object, and you're not sure about how it will be used. But, if you need an object for the lifetime of a method body, then release it at the end of the method, don't use autorelease. That way you have a complete view of the object lifecycle, therefore it's a good memory management method.
The following sums some of these functions up, thanks to apple's references.
· Alloc : Class method of NSObject. Returns a new instance of the receiving class.
· Init : Instance method of NSObject. Implemented by subclasses to initialize a new object (the receiver) immediately after memory for it has been allocated.
· New : Class method of NSObject. Allocates a new instance of the receiving class, sends it an init message, and returns the initialized object.
· Release : Instance method of NSObject delegate. Decrements the receiver’s reference count.
· Autorelease : Instance method of NSObject delegate. Adds the receiver to the current autorelease pool.
· Retain: Instance method of NSObject delegate. Increments the receiver’s reference count.
· Copy : Instance method of NSObject delegate. Returns a new instance that’s a copy of the receiver.
So to sum up some basic rules of thumb
· alloc goes with init
· new = alloc + init
· you cannot release an object that you are not owner of
· object can have more than one owner
· to share ownership, use retain or copy
· autorelease is not a bad practice
· objects you create that are not released are leaks
· never call dealloc yourself - just call release.