Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone Memory Management

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?

like image 212
Skoota Avatar asked Nov 20 '25 21:11

Skoota


2 Answers

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 contains copy. 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 sent retain to, 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 the release or autorelease message.

The first method using self uses 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 @property declaration (for example if you specified retain, the setter will retain the new value and release the old value).

The second method sets up a pointer to an NSMutableArray and passes it off to your property setter via self, which will most likely retain it, thereby bringing the reference count up to 2, since the object was previously alloc-ed, so you need to release it after this line to bring it back down to 1.

The third method will not work, because you are releasing an object with a reference count of 1 at the point of invoking release. How so you ask? Well, the first line sets up a pointer to an alloc-ed object, then directly assigns it to your instance variable, which will just point the ivar to the same object that theArrayVariable is pointing to. Then, that same object that theArrayVariable is pointing to gets sent the release method, which will effectively bring down the reference count of your ivar as well as the receiver, to 0. At this point both your instance variable and theArrayVariable will get deallocated.

like image 187
Jacob Relkin Avatar answered Nov 23 '25 10:11

Jacob Relkin


a) The general rule for objective-c is that if you alloc it you must release it. In the first example, the method is returning a pointer to an object that already exists, and therefore you are not responsible for releasing it. In the second example, the first like is pointless since you aren't using allocated memory for stored image. This may cause a memory leak.

b) The first two are just stylistic differences, with no difference in outcome. In those, you will be left with arrayVariable pointing to the object returned by [[NSMutableArray alloc] init]; (assuming you have retain in the @property declaration) and you should release it in the -dealloc method. As stated above, the third will not work because you are merely passing off the pointer.

Here is a useful article for understanding obj-c memory management: http://memo.tv/memory_management_with_objective_c_cocoa_iphone

like image 40
Jumhyn Avatar answered Nov 23 '25 12:11

Jumhyn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!