0

If I create an NSObject class with a method that returns an NSMutableArray do I need to release the array inside the class or does the Class never retain?

Not sure on how to explain so here is some code:

@implementation PointsClass

- (NSMutableArray *)pointsForLevel 
{
NSMutableArray *_points = [NSMutableArray new];

   [_points addObject:[NSValue valueWithCGPoint:CGPointMake(521, 279)]];
   [_points addObject:[NSValue valueWithCGPoint:CGPointMake(321, 491)]];
   [_points addObject:[NSValue valueWithCGPoint:CGPointMake(419, 477)]];

return _points;
}

@end

If i call this method from a ViewController like this:

PointsClass *pointsClass = [PointsClass new];
NSMutableArray *points = [pointsClass pointsForLevel];
[pointsClass release];

Do I only need to release the pointers Array? Has the _points array been retained at all?

EcksMedia
  • 461
  • 2
  • 5
  • 20

2 Answers2

2

new will give you an object with a retain count of 1. So, yes, you do need to balance this with a release somewhere.

The convention here is to return [_points autorelease] and then let the caller decide if he needs to retain the array for some period of time.

Firoze Lafeer
  • 17,133
  • 4
  • 54
  • 48
  • Thanks Firoze, this is kind of what my issue is. If I use _points = [[NSMutableArray new]autorelease]; my app crashes. – EcksMedia May 29 '11 at 04:56
  • @EcksMedia Firoze is correct. Calling [pointsClass pointsForLevel] delivers the autoreleased NSMutableArray. So now that caller must retain it as long at is needed. Probably you can add more code to see where the points variable is actually used? – marcus May 29 '11 at 06:44
0

Apple's Memory Management Programming Guide (which you should absolutely read) sums it up best:

  • You only release or autorelease objects you own.
  • You take ownership of an object if you create it using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message.
  • You use release or autorelease to relinquish ownership of an object. autorelease just means “send a release message in the future” (specifically: when the used autorelease pool receives a drain message—to understand when this will be, see “Autorelease Pools”).

Because you created it with "new", you are responsible for releasing it. I would recommend instead, one of the following:

  • autorelease _points before returning it. The caller can then decide whether to retain it or not, or...
  • rename your method to reflect the fact that the object returned by it must be release (like newPointsForLevel).

In addition, you're creating an instance of PointsClass (via new), and not assigning it to a variable. That's a memory leak.

A couple other pointers:

  • alloc/init is generally preferred over new, although they are functionally identical. See here for more info on the topic.
  • I wouldn't recommend naming local variables with a leading underscore - that's usually reserved for instance variables.
Community
  • 1
  • 1
zpasternack
  • 17,838
  • 2
  • 63
  • 81
  • Thanks for the response, I totally understand that if I create an object you need to release it but the issue that I am having in this example is where to release? Autorelease crashes my app. I am looking at releasing through dealloc which i think may be the correct thing to do. Also, thanks for the tip on not assigning PointsClass to a var, I have rectified this in my code and will do in the example above. – EcksMedia May 29 '11 at 05:17