• 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: 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

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

  • Prev by Date: Re: indexOfTabViewItemWithIdentifier keeps crashing App SOLVED
  • Next by Date: Re: Retain/release question
  • Previous by thread: Re: Retain/release question
  • Next by thread: Re: Retain/release question
  • Index(es):
    • Date
    • Thread