views:

36

answers:

1

I have been struggling with the best pattern for returning an array from a static method.

In my static method getList (in the BIUtility Class), I am allocating an NSArray to return. in the return line, I do:

return [array autorelease];

Then in the calling method, I am allocating an array like this:

NSArray * list = [[[NSArray alloc] initWithArray:[BIUtility getList]] retain];

Later I release the list using:

[list release];

I think this is causing a memory leak as the retain is increasing the retain count one too many. However, if I do not do the retain, I get a Bad_Exec because it has already freed the class.

I feel like I am overthinking this and there must be a typical pattern. I have been looking all over the place and I cannot find a "best practice".

I appreciate your help.

+1  A: 

You should replace:

NSArray * list = [[[NSArray alloc] initWithArray:[BIUtility getList]] retain];

With:

NSArray * list = [[BIUtility getList] retain];

This is because getList actually returns a pointer to the NSArray.

If it were a mutable array, however, you should say [[BIUtility getList] copy]; so that you don't accidentally mutate an array that another object has a reference to.

If you are curious, you were getting a memory leak because your original statement increments two counters, while you only release one later.

These parts of the statement increase counts:

 [anObject]] retain]
 [anClassname alloc]

[anObject copy] will also create an object with a count of 1.

Chris Cooper
I did this, but then I get the EXC_Bad_Instruction message because it is trying to do the release on an object that has been released already. DO I not need to do an explicit release on the retained object?
Michael Bordelon
@Michael: How do you declare the array originally?
Chris Cooper
Like this...NSArray *moveList = [[NSArray alloc] init];Sometimes I have to use a NSMutableArray because I am building it from a SQL query, but I return a NS Array.
Michael Bordelon
If you declare is as [alloc], return it as [autorelease] and then [retain] it when you make the method call, you should be fine to use it until the next time you release it. If you are still having problems after that setup, it is somewhere else in your program.
Chris Cooper