Yes this
lookUp: method does leak if no match is found and it also leaks when
lookUp: is called again without releasing the previous
theList in
main.
You release the array in the main program that is assigned to the array in the method, but does that release the memory for both? Even if it does, if you return no results, then it's never assigned.
There is only one object (array) here (created by calling
alloc).
theList variable in the method and
theList variable in
main are merely pointers to an object... they aren't objects themselves and in this case they both point to the same object.
Think of an object as your house and a pointer to the object as your street address. You can give out your address to as many people as you want... but you still have only one house.
What I'm having trouble with is how best to handle this - it seems that having to remember to release the object in the main program is rather inelegant, but I'm not sure what alternatives there are....
Inelegant method #1:In the
lookUp: method have
theList released if no match is found.
if (theList.count != 0)
return theList;
else
{
[theList release];
return nil;
}
And then in
main make sure you release
theList after each lookup. For example...
NSLog(@"Looking up \"Harry Potter\"");
theList = [book lookUp: @"Harry Potter"];
if ( theList != nil)
{
[book listMatches: theList ];
[theList release];
}
else
NSLog(@"No matches found");
Inelegant method #2:Always return
theList from the
lookUp: method even if no match was found.
-(NSMutableArray *) lookUp: (NSString *) theName;
{
NSMutableArray *theList = [[NSMutableArray alloc] init];
for ( AddressCard *theCard in book)
if ( [theCard.name caseInsensitiveCompare: theName ] == NSOrderedSame )
[theList addObject: theCard];
return theList;
}
Then in
main change the way you check for a successful lookUp. For example:
NSLog(@"Looking up \"Harry Potter\"");
theList = [book lookUp: @"Harry Potter"];
if ([theList count])
[book listMatches: theList];
else
NSLog(@"No matches found");
[theList release];
Elegant method:Skip ahead and read chapter 17. Then change the
lookUp: method to use
autorelease.
-(NSMutableArray *) lookUp: (NSString *) theName;
{
NSMutableArray *theList = [[[NSMutableArray alloc] init] autorelease];
for ( AddressCard *theCard in book)
if ( [theCard.name caseInsensitiveCompare: theName ] == NSOrderedSame )
[theList addObject: theCard];
if (theList.count != 0)
return theList;
else
return nil;
}
Then keep
main the same as the original code but
don't call
[theList release];