views:

1303

answers:

1

I am cleaning up my code in a phonebook iPhone application and the Leaks tool in Instruments is reporting that I am leaking NSCFString objects. Here is the pattern that I am following:

I have a Person class in my application that has nothing more than local NSString members and associated properties for first name, last name, etc.

My view controller has an NSMutableArray property that is populated from a SQLite database in the searchBarSearchButtonClicked event. This NSMutableArray is populated with Person object(s) that will be used to populate my tableview control. Also, if the user clicks on a person in the view, their Person object will be passed to the Detail view for viewing additional information than just the name.

When I perform my first look up and display the results there are no memory leaks.

Now, when I perform my second look up I would ideally like to clear out the NSMutableArray and reload it with the new result set without leaking memory. So, to do this, I call removeAllObjects on my personList property and then call the database to repopulate the personList NSMutableArray as shown below:

[self.personList removeAllObjects];
self.personList = [SearchService GetPersonList:searchText];
[list reloadData];

By calling removeAllObject I've gotten rid of the leaks that I used to have that were associated with the Person objects. However, it appears that I am now leaking the NSString objects left over from the properties of the individual Person objects.

Is this possible?

I am new to the Instruments tool but from what I can tell from the Extended Detail when I drill into one of the NCSFString leaks is that last line of code in the stack is often pointing to the @synthesize line of code for the property, such as:

@synthesize firstName;

So, that is why I think those NSStrings are not getting cleaned up. Is there a better way to do this that doesn't produce memory leaks?

+1  A: 

Do you release the NSStrings in the dealloc method for your Person class?

Assuming that you set up your property as so:

@property (retain) NSString *firstName;

When you set firstName using the setter, it will be retained. If the Person instance is then released and deallocated, but firstName has not been released it will leak.

Put it in the dealloc method in your Person class:

- (void)dealloc
{
    [firstName release];
    [super dealloc];
}

(Assuming the corresponding ivar that is used for your firstName property is called firstName).

Perspx
This appears to work. However, the code analyzer in XCode 3.2.1 comments on my release in the dealloc method: "Incorrect decrement of the reference count of an object is not owned at this point by the caller". Ideas?
rtemp
The code analyzer considers using accessor methods in `-dealloc` a bug and warns you of this – there is some debate about whether it is valid to use accessors in `init` and `dealloc` but I think the general consensus is to steer clear and access the ivars directly (sorry should have pointed that out before).
Perspx