Утечка памяти при прикосновении какао с помощью mutableCopy - PullRequest
1 голос
/ 30 января 2011

Я пытаюсь устранить утечку памяти, но не могу найти решение.

Приборы говорят, что в этом методе есть утечка:

 - (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 объявлен в моем .h как NSMutableArray, и у него есть свойство: @property (nonatomic, retain) NSMutableArray *newsArray;

Я много чего пробовал, но все время ничего не получалось. Я использую XCode 3.2.5 с iPhone SDK 4.2.1 и Instruments 2.7.

Ответы [ 2 ]

12 голосов
/ 30 января 2011

Когда вы делаете

self.newsArray = something; 

, что something сохраняется, потому что вы добавили retain к свойству newsArray.

Но mutableCopy также возвращает объект с счетом хранения, увеличенным на 1. Таким образом, после завершения метода ваш newsArray имеет счет сохранения на единицу выше, чем вы действительно хотите, что является обнаруженной утечкой памяти.

Решение: замените строку, которой вы назначаете self.newsArray, на

self.newsArray = [[[managedObjectContext executeFetchRequest:coreDataNewsFetchRequest error:nil] mutableCopy] autorelease];
3 голосов
/ 30 января 2011

mutableCopy делает копию и сохраняет ее, поэтому вам нужно освободить созданную вами копию. Попробуйте изменить это:

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

К этому:

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

Кроме того, создание нового объекта класса делегата приложения немного необычно и может не дать ожидаемого результата. Обычно вы создаете экземпляр одного делегата приложения (по умолчанию это делается для вас в MainWindow.xib), а затем ссылаетесь на него во всем приложении, используя:

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