Objective-C : Memory Management Methods
we learn polymorphism in ObjC : Objective-C : Polymorphism
object is allocated, it's counting references is 1. When that count reaches 0,
method is called, freeing memory; that way, you don't end up with leaks. release
decrements with count, while retain increments it.
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
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.
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)
str1 = [[NSString alloc]initWithString:@"foo bar"]];
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
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 ?
what is retain ?
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.
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
should be used when you want to make sure your object will not be released.
Actually it's a convention
I recommend the reading of this thread
that I started.
is 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.
following sums some of these functions up, thanks to apple's
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
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
never call dealloc yourself - just call release.