Re: Retain/release question
Re: Retain/release question
- Subject: Re: Retain/release question
- From: Jeff Gilbert <email@hidden>
- Date: Fri, 10 Dec 2004 14:01:19 -0600
Hi Bruce,
On Friday, December 10, 2004, at 01:08PM, Bruce Truax <email@hidden> wrote:
>I am still struggling with the retain/release concept. I hope someday to
>fully understand it. Most of the time I end up with the correct pairing
>because I poke around and look at the retain count and because most times it
>does not make much difference. I now have a case where I want to create a 2
>dimensional NSArray from a C array of floats and I have upwards of 200,000
>elements in the array so I don't want to have a lot of improperly retained
>variables. Below I have included the source code to the function which
>creates the array. Could someone provide me with the proper retain/release
>protocol? Should I set up an autorelease pool for this function?
>
>When I call the function I the calling statement is:
>
> [self setDisplayArray:[self buildArrayFromCArray:outputArray
> ofSize:numberOfPoints
> withXDimension:xSize
> withYDimensiont:ySize]];
>
>
>When I call this setter function and the display array is released I want to
>make sure that all of the row arrays are also released.
>
>- (NSMutableArray *)buildArrayFromCArray:(float*)input
> ofSize:(int)nPoints
> withXDimension:(int)xDimension
> withYDimensiont:(int) yDimension
>{
> NSMutableArray *theArray;
> int column=0;
> int row=0;
> int i=0;
>
> theArray = [[NSMutableArray alloc] initWithCapacity:xDimension];
> for (column = 0; column<xDimension; column++){
> NSMutableArray *rowArray = [[NSMutableArray
>alloc]initWithCapacity:yDimension];
> for (row = 0;row<yDimension; row++){
> NSNumber *point = [[NSNumber alloc] initWithFloat:input[i]];
> [rowArray addObject:point];
> i++;
> }
> [theArray addObject:rowArray];
> }
> return theArray;
>}
You need to add some release calls in your code.
[[NSMutableArray alloc]initWithCapacity:yDimension] creates an array with a refcount of 1. When you use [theArray addObject:rowArray] to add it to theArray, theArray takes ownership of rowArray and increments the refcount to 2. So, you should use [rowArray release] to release the reference added by initWithCapacity:.
Similarly, [[NSNumber alloc] initWithFloat:input[i]] creates a number with refcount 1. [rowArray addObject:point] takes ownership of point and bumps the refcount to 2. Use [point release] to release the refcount added with initWithFloat:.
Creating theArray with [[NSMutableArray alloc] initWithCapacity:xDimension] has a refcount of 1. When you return this array to the caller, the caller assumes responsibility for releasing the reference added by initWithCapacity:. If you do not want the caller to do this, typically you would use an autoreleased array by doing theArray = [NSMutableArray arrayWithCapacity:xDimension]; Now, theArray will be autoreleased by the autorelease pool. From the way you are calling buildArrayFromCArray: it seems that you should be returning an autoreleased array, since the caller does not actually store the return value so it can release it later.
To make the semantics of buildArrayFromCArray:... clear about whether the caller should release the returned array, I suggest that you follow Cocoa naming guildlines. If you create an autoreleased array, name the method arrayFromCArray:... If you want the caller to release the array, name your method createArrayFromCArray:... Typically, a method with init, copy or create in the name means that the caller is responsible for releasing the returned object.
A more correct version of this method (including additional releases) is:
- (NSMutableArray*)arrayFromCArray:(float*)input
ofSize:(int)nPoints
withXDimension:(int)xDimension
withYDimensiont:(int)yDimension
{
NSMutableArray *theArray;
int column=0;
int row=0;
int i=0;
theArray = [NSMutableArray arrayWithCapacity:xDimension];
for (column = 0; column<xDimension; column++){
NSMutableArray *rowArray = [[NSMutableArray alloc]initWithCapacity:yDimension];
for (row = 0;row<yDimension; row++){
NSNumber *point = [[NSNumber alloc] initWithFloat:input[i]];
[rowArray addObject:point];
[point release]; // rowArray takes ownership of point
i++;
}
[theArray addObject:rowArray];
[rowArray release]; // theArray takes ownership of rowArray
}
return theArray;
}
Refcounting can be confusing at first. It does get easier with experience (like most things).
Good luck,
Jeff Gilbert
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden