Generic-user-small Marc Winoto 13 posts

I’ve read the Memory Management Rules document in the Xcode documentation. I’m not sure I get it. (BTW I am programming for iPhone).

Say, I do:

- (NSMutableArray) stuff
{
   NSMutableArray * marr = [NSMutableArray arrayWithCapacity:10];
   // DB call. Put results in marr
   return marr;
}

-(void) doSomethingWithStuff
{
    NSMutableArray * stuff = [self stuff];
    [stuff retain];
    //Do something
    [stuff release];
    return;
}

Having some C background this seems a little weird to me. If the array is allocated, and not freed, it seems to me that is should be safe to just release (maybe release!=free?). But if I remove the retain and keep the release, I get an error:

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0×00000000c014c9cf
Crashed Thread: 0

Alternatively, dropping the retain and release calls also works. But then when does the array get marked for deletion? Have I caused a leak in this case?

 
Generic-user-small Paul Wilson 17 posts

I’ve been struggling with the same stuff myself, so glad it’s not just me ;-)

If you’d done


NSMutableArray * marr = [[NSMutableArray alloc] initWithCapacity:10];

then you’d be perfectly correct to release it. It would start with a retainCount of 1; releasing it would lower that to 0 and the memory would be freed. However you used the static factory method arrayWithCapacity, which I believe is equivalent to


NSMutableArray * marr = [[[NSMutableArray alloc] initWithCapacity:10] autorelease];

The allocated array is added to an autorelease pool. My understanding is that a release message is sent to all the objects in the pool when that pool is deallocated. I also believe that the pool in question will be associated with the event (eg button press) in which the array was allocated. So by releasing the object yourself release will be called one more time than it ought to be causing the exception. Please guys, correct me if I’m wrong.

At the bottom of this page in the Apple Docs, there are a set of handy rules which explain when and when not to release objects. These include

If you create an object using a class factory method (such as the NSMutableArray arrayWithCapacity: method), assume that the object you receive has been autoreleased. You should not release the object yourself and should retain it if you want to keep it around.

 
Generic-user-small Marc Winoto 13 posts

Thanks. That worked!

3 posts, 2 voices