• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Retain/release question
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


References: 
 >Retain/release question (From: Bruce Truax <email@hidden>)

  • Prev by Date: Re: Retain/release question
  • Next by Date: Re: Kill other process's warning dialog
  • Previous by thread: Re: Retain/release question
  • Next by thread: Re: Retain/release question
  • Index(es):
    • Date
    • Thread