views:

85

answers:

1

I'm new to iPhone development, and I've just run my iPhone app throught the Intruments Leaks tool for the first time, and discovered a leak with my ListViewController dataArray method.

When I click on the listing it shows the code, and a few lines have percentages next to them. Presumably they're the lines that are leaking memory. I've pasted the code and the percentages below:

- (NSArray*) dataArray {
   MapViewController *map = mainWindow.mainView.mapView;
NSMutableArray *data = [NSMutableArray arrayWithCapacity: 0]; /** REPORTS 25.3% HERE **/

if (selectedIndex == 1 || selectedIndex == 0)
 [data addObjectsFromArray: DataSource.data]; /** REPORTS 7.4% HERE **/

if (selectedIndex == 2 || selectedIndex == 0)
 [data addObjectsFromArray: DataSource.additionalData]; /** REPORTS 67.4% HERE **/

   [data sortUsingSelector:@selector(compareAnnotation:)];

   dataArrayNeedsUpdating = NO;
[data retain];
dataArray = data;

   return data;
}

Is there anything I can change in that code to prevent the leak, or will changes need to be made in the calling code?

Thanks in advance,

Ben

+5  A: 

If dataArray is storing a value when this method is called, it will leak, because you're not releasing the old value before you overwrite it. The simple solution is to use a setter (probably one generated by @synthesize) and change the lines

[data retain];
dataArray = data;

to the simpler (and more conventional)

[self setDataArray:data];

or, if you prefer,

self.dataArray = data;

The difference between

myMemberVariable = somePointerToAnObject;

and

self.myMemberVariable = somePointerToAnObject;

is one of the subtle gotchas for the new Objective-C coder.

Seamus Campbell
That certainly seems to have fixed it, thanks! Can you explain (or link to) the difference between myMemberVariable and self.myMemberVariable?
Ben Dowling
Object variables (that you define in your @interface in your .h files) are local variables in all of your object methods (those defined with '-' before the return type, which is in contrast to class methods, which are '+'). So you can always refer to your variable directly by name. Which is what you've done. The dot notation is a shorthand for properties. If you use it to access the value, the method with the same name is called (e.g. [self myMemberVariable]) and if you use it to set the value, [self setMyMemberVariable] is called. Normally you make those methods automatically when ...
Seamus Campbell
... you @synthesize a property. The setter is what's relevant here. The automatically-created setter will release the old value (if the property is a 'retain' property), retain the new value, and set the variable. All of this would be a little more clear, but the convention is to name your property with the same name as your instance variable (or "ivar") so the end result is that they look very similar.
Seamus Campbell
Ah ok - that definitely explains it. It also explains why I didn't need to change the initial "return dataArray" to "return self.dataArray". Thanks!
Ben Dowling