Jacksonkr
Jacksonkr

Reputation: 32237

why do you make temporary objects, set them to variables, then release them?

I often see something like:

NSArray *tmpArr = [[NSArray alloc] initWithObjects:@"Info", nil];
self.userInfo = tmpArr;
[tmpArr release];

instead of:

self.userInfo = [[NSArray alloc] initWithObjects:@"Info", nil];

Does anyone know why the top code sample is more popular? Is it more correct memory management than the second?

Upvotes: 1

Views: 815

Answers (3)

Daniel Schneller
Daniel Schneller

Reputation: 13926

Apart from any other reasons there might be, it makes the code more readable and helps to prevent errors.

Your two examples are not equivalent, because you forgot to release the newly alloc/init'ed array in the second one. You would have needed

self.userInfo = [[[NSArray alloc] initWithObjects:@"Info", nil] autorelease];

here.

QED first reason ;-P

Moreover, when you create a local variable first, you can build up more complex objects before publicizing them via a property. If, for example, you were using a mutable array here and filled it with some more complex logic, assigning it to the property right away and only when going on filling it up, clients of your class might access the property with its contents being only half ready – a great provision for sporadic and hard to reproduce bugs.

So even though in your case it would not have been strictly necessary to use a local variable (if you either had autorelease'd it our used the new Automatic Reference Couting "ARC", which would have solved the leak issue automatically), in my opinion it is always a good idea to first get everything ready and then make it visible.

Clean code rules :)

Upvotes: 2

IronMensan
IronMensan

Reputation: 6831

Assuming that the property userInfo is marked retain, the second form will leak memory. [[NSArray alloc] initWithObjects] will create an array with a reference count of one. Assigning it to a retain property will increase the reference count to two and it will never come back down to zero and be released. It can be fixed either by using the first form you listed or by:

self.userInfo = [[[NSArray alloc] initWithObjects:@"Info", nil] autorelease];

so that the auto release will decrement the reference count to one at the next iteration of the run loop. From then when userInfo is cleared, the reference count will go down to zero and the array will be destroyed.

You should also take a look at this question

Upvotes: 2

ayoy
ayoy

Reputation: 3835

Second code snippet causes a memory leak due to the array not being released. In most cases properties of object types (like NSArray in this case) are either retain or copy properties and this means they either increase the reference count of the assigned value or copy the whole object. Then the local variable can be (and should be) released if it's not needed anymore.

Non-leaking alternative to the second code snipped would be using autorelease:

self.userInfo = [[[NSArray alloc] initWithObjects:@"Info", nil] autorelease];

or simply:

self.userInfo = [NSArray arrayWithObjects:@"Info", nil];

Upvotes: 5

Related Questions