al.one
al.one

Reputation: 111

Memory leak in cocoa touch with a mutableCopy

I'm trying to resolve a memory leak but I can't find any solution.

Instruments says that there is a leak in this method:

 - (void)refreshData {

 Sn0werSp33dAppDelegate *appDelegate = [[Sn0werSp33dAppDelegate alloc] init];
 NSFetchRequest *coreDataNewsFetchRequest = [[NSFetchRequest alloc] init];
 NSEntityDescription *entity = [NSEntityDescription entityForName:@"News" inManagedObjectContext:managedObjectContext];

 [coreDataNewsFetchRequest setEntity:entity];

 self.managedObjectContext = appDelegate.managedObjectContext;
 self.newsArray = [[managedObjectContext executeFetchRequest:coreDataNewsFetchRequest error:nil] mutableCopy];//Intruments says that here is the memory leak :(


 [appDelegate release];
 [coreDataNewsFetchRequest release];
 [entity release];
}

newsArray is declared in my .h as an NSMutableArray and it has a property: @property (nonatomic, retain) NSMutableArray *newsArray;

I've tried many things but at all times, that things weren't working. I'm running XCode 3.2.5 with iPhone SDK 4.2.1 and Instruments 2.7.

Upvotes: 1

Views: 5003

Answers (2)

Simon Whitaker
Simon Whitaker

Reputation: 20576

mutableCopy makes a copy and retains it, so you need to release the copy you've created. Try changing this:

self.newsArray = [[managedObjectContext executeFetchRequest:coreDataNewsFetchRequest 
                                                      error:nil] mutableCopy];

To this:

self.newsArray = [[[managedObjectContext executeFetchRequest:coreDataNewsFetchRequest 
                                                       error:nil] mutableCopy] autorelease];

As an aside, creating a new object of your app delegate class is a little unusual and might not give you the result you expect. Conventionally you instantiate one app delegate (by default this is done for you in MainWindow.xib) and then refer to it throughout your app using:

FooAppDelegate *appDelegate = (FooAppDelegate*)[[UIApplication sharedApplication] delegate];

Upvotes: 3

mrueg
mrueg

Reputation: 8225

When you do

self.newsArray = something; 

that something is retained, because you added retain to the newsArray property.

But mutableCopy also returns an object with a retain count increased by 1. So after the method finishes, your newsArray has a retain count one higher than what you really want, which is the memory leak that was detected.

Solution: Replace the line where you assign self.newsArray with

self.newsArray = [[[managedObjectContext executeFetchRequest:coreDataNewsFetchRequest error:nil] mutableCopy] autorelease];

Upvotes: 12

Related Questions