Re: Retain/release question
Re: Retain/release question
- Subject: Re: Retain/release question
- From: Bob Ippolito <email@hidden>
- Date: Fri, 10 Dec 2004 15:07:20 -0500
On Dec 10, 2004, at 11:05 AM, Bruce Truax 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;
}
There are several retain count issues with the following example.
Well, "several" in this case means that every object except for self is
managed incorrectly and will be leaked!
The rule of reference counting is that you should have a net retain
count of ZERO for every object in every method, EXCEPT when persisting
that object beyond the scope of the method (as in, a setter). In these
cases, you will release the object later, typically in dealloc or a
future call to the setter. Setters should retain their argument,
release the instance variable, and then set the instance variable to
the argument in that order (this is important!).
What other methods do is not of your concern! ONLY take init, retain,
release, and autorelease into account if it happens *in* the method.
While addObject: does increment the retain count of an object in its
implementation, that is NOT of your concern, because presumably
NSMutableArray does not have reference counting bugs.
Also, NEVER look at [obj retainCount] unless you absolutely know that
you have to and you understand everything that is happening to that
object. Its value is an implementation detail and may have "strange"
values for some objects (singletons, immutable values, etc.). ONLY
consider what *your code* is doing using the rule above when looking
for reference counting errors.
As for your code, there are four problems:
1. theArray is returned with a net retain count of 1. It should be
autoreleased before you return it. setDisplayArray SHOULD NOT release
its argument.
2. every rowArray has a net retain count of 1. It should be released
after [theArray addObject:].
3. every point has a net retain count of 1. It should be released
after [rowArray addObject:].
4. You should NOT release the return value of buildArray from your
setter. See the above rule for what your setter should do.
You typically do not need to manage your own NSAutoreleasePool unless
you are doing this in a separate thread. In that case it's up to your
better judgment as to when they should be pushed and popped. Nearly
always, you should create one when your thread starts, and release it
when your thread is about to finish. Sometimes, you should create and
release additional NSAutoreleasePools if you expect to create a large
number of autoreleased objects and you are not doing so from an
NSRunLoop. NSRunLoop should manage additional release pools itself, at
least one per iteration. Note again that the need to manage your own
NSAutoreleasePools with that kind of granularity IS NOT COMMON, and is
definitely not necessary in the scenario you are describing. There is
only one autoreleased object (theArray), and you're probably performing
this code from a NSRunLoop-driven thread anyway.
-bob
_______________________________________________
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