IPhone SDK - утечка памяти с помощью executeSelectorInBackground - PullRequest
0 голосов
/ 14 марта 2010

Может быть, кто-то может помочь мне с этой странной вещью:

Если пользователь нажимает кнопку, на контроллер навигации добавляется новый UITableView. Это новое представление выполняет запросы к базе данных, что занимает некоторое время. Поэтому я хотел сделать загрузку в фоновом режиме.

Что работает БЕЗ утечки памяти (но экран зависает, пока все не будет сделано):

WorkController *tmp=[[WorkController alloc] initWithStyle:UITableViewStyleGrouped];
self.workController=tmp;
[tmp release];

[self.workController loadList]; // Does the DB Query
[self.workController pushViewController:self.workController animated:YES];  

Теперь я попытался сделать это:

    // Show Wait indicator
    ....

    WorkController *tmp=[[WorkController alloc] initWithStyle:UITableViewStyleGrouped];
    self.workController=tmp;
    [tmp release];

    [self performSelectorInBackground:@selector(getController) withObject:nil];
}

-(void) getController {
    [self.workController loadList]; // Does the DB Query
    [self.navigationController pushViewController:self.workController animated:YES];
}

Это тоже работает, но утечка памяти, и я не знаю почему! Вы можете помочь?

Кстати - может ли приложение попасть в AppStore с небольшой утечкой памяти? Или это будет проверено в первую очередь?

Заранее спасибо!

Ответы [ 2 ]

5 голосов
/ 14 марта 2010

Нет, небольшие утечки памяти (скорее всего) не будут отклонять ваше приложение из магазина приложений.

В вашем примере, когда вы запускаете свой метод в отдельном потоке, вы должны создать и утилизировать объект NSAutoreleasePool для этого потока для обработки автоматически выпущенных объектов. Следующие изменения в методе getController должны помочь:

-(void) getController {
    NSAutoreleasedPool *pool = [[NSAutoreleasedPool alloc] init];

    [self.workController loadList]; // Does the DB Query
    [self.navigationController pushViewController:self.workController animated:YES];

    [pool release];
}

Подробнее см. Автозапуск пулов в руководстве по управлению памятью. Соответствующая цитата оттуда:

Если вы создаете вторичный поток, вы должен создать свой собственный пул автоматического выпуска как только начинается нить выполнения; в противном случае вы будете течь объекты. (См. «Автозапуск пулов и Нитки » для деталей.)

0 голосов
/ 30 марта 2011

Кстати, вы звоните pushViewController: из фонового потока.Это плохо.

Вы должны делать что-то только с пользовательским интерфейсом - например, выдвигать контроллеры представления и изменять элементы пользовательского интерфейса - из основного потока.Если вы этого не сделаете, все пойдет не так.

См. Раздел «Руководство по основным принципам какао», озаглавленный «Безопасна ли структура потоков какао?»: Там написано «Все объекты UIKit следует использовать только в основном потоке».*

...