There are a few concepts about iPhone memory management that have got me confused, so I was hoping that someone could clarify these.
(a) Say that I am calling a function which returns an image, and I want to store that returned image in a variable so that I can assign it to various other variables without having to re-call the image generation function each time. At the moment I am doing the following:
UIImage *storedImage = [someFunction returnImage];
and because the storedImage is not alloc‘ed I am not releasing the variable.
However, should I be explicitly alloc‘ing and releasing the UIImage instead?
UIImage *storedImage = [[UIImage alloc] init];
storedImage = [someFunction returnImage];
...do stuff...
[storedImage release];
What is the implication of doing the direct assignment without alloc rather than alloc‘ing the variable and then assigning?
(b) In the init method for various classes I am setting up the instance variables. At the moment I am doing the following:
self.arrayVariable = [[NSMutableArray alloc] init];
However, I have seen others do the assignment this way:
theArrayVariable = [[NSMutableArray alloc] init];
self.arrayVariable = theArrayVariable;
[theArrayVariable release];
or
theArrayVariable = [[NSMutableArray alloc] init];
arrayVariable = theArrayVariable;
[theArrayVariable release];
…which is the same as above, but without the self.
What is the difference between the three methods and which is better to use?
Regarding returning objects from methods, you should always return an autoreleased object from any method which does not begin with the name
alloc,new, or containscopy. This is defined in Apple’s object ownership policy, which states that you own any object that you create (“create” is defined as an object which you sentretainto, or used any of the aforementioned messages to retrieve an object), and that you are responsible for relinquishing ownership of that object by sending it thereleaseorautoreleasemessage.The first method using
selfuses the property setter to set the instance variable to the argument (in this case whatever is on the RHS of the assignment).This will do whatever you specified in your
@propertydeclaration (for example if you specifiedretain, the setter willretainthe new value andreleasethe old value).The second method sets up a pointer to an
NSMutableArrayand passes it off to your property setter viaself, which will most likelyretainit, thereby bringing the reference count up to2, since the object was previouslyalloc-ed, so you need toreleaseit after this line to bring it back down to1.The third method will not work, because you are
releasingan object with a reference count of1at the point of invokingrelease. How so you ask? Well, the first line sets up a pointer to analloc-ed object, then directly assigns it to your instance variable, which will just point the ivar to the same object thattheArrayVariableis pointing to. Then, that same object thattheArrayVariableis pointing to gets sent thereleasemethod, which will effectively bring down the reference count of your ivar as well as the receiver, to0. At this point both your instance variable andtheArrayVariablewill get deallocated.