Dmitri
Dmitri

Reputation: 1378

Proper way to de-allocate array of objects in Objective C

I am new to Objective-C and still don't completely grasp the memory management. I have an NSMutableArray of pointers...

NSMutableArray *itemArray;

throughout my program, I add items to it.

//start loop    
MyItem *x = [[MyItem alloc] init];
[itemArray addObject:x];
//end loop

There comes a point when I want to toss all items in the array and re-populate it. Do I just loop through the whole array and send a release message to every object in the array as my intuition tells me, and then removeAllObjects, or does removeAllObjects take care of decrementing all the reference counts? Is the following correct?

//start loop
[[itemArray objectAtIndex:i] release];
//end loop
[itemArray removeAllObjects];

Upvotes: 1

Views: 299

Answers (3)

jtbandes
jtbandes

Reputation: 118681

The real problem you have is this:

//start loop    
MyItem *x = [[MyItem alloc] init];
[itemArray addObject:x];
//end loop

You're allocating an object (so you have ownership), then sticking it in the array and never releasing it. You should do this:

//start loop    
MyItem *x = [[MyItem alloc] init];
[itemArray addObject:x];
[x release];
//end loop

or this:

//start loop    
MyItem *x = [[[MyItem alloc] init] autorelease];
[itemArray addObject:x];
//end loop

Once you add it to the array, the array will take ownership by retaining the object, so you don't have to keep it retained yourself. And when you call -removeAllObjects, the array will release them as appropriate. Basically, once you hand it off to the array, you don't have to worry about it.

<Obligatory ARC plug>

You should start getting used to using ARC, where you won't have to worry about releasing the object at all, because the compiler will do it for you.

Upvotes: 5

Perception
Perception

Reputation: 80603

The 'add' group of methods on NSArrays retain the objects you pass in, and the remove 'group' of methods release them, so you are ok using your second method. Your first method actually (sending release to each object then calling removeAllObjects), will most likely result in a BAD_EXEC_ACCESS exception being thrown.

Upvotes: 1

Seamus Campbell
Seamus Campbell

Reputation: 17906

Just call -removeAllObjects. Objects added to an NSArray are retained by the array and released when they are removed.

Note that if you create an object with +alloc you must also release it somewhere with a matching -release or -autorelease. It appears that you don't have one when you are creating your objects. Either:

MyItem *x = [[[MyItem alloc] init] autorelease];
[itemArray addObject:x];

or

MyItem *x = [[MyItem alloc] init];
[itemArray addObject:x];
[x release];

will work.

Upvotes: 2

Related Questions