Отслеживание утечек памяти какао - PullRequest
2 голосов
/ 18 ноября 2009

В моем приложении появляются сообщения об утечках памяти, но я не могу точно отследить, что происходит. У меня есть функция, которая убирает старый вид и заменяет новый. Я не использую NavControllers или любые @properties; Я управляю своим окном верхнего уровня напрямую.

-(void)swapInView:(UIViewController*)newViewController
{
    [currentViewer.view removeFromSuperview];
    printf("Old viewController (%p) has count of %d; now releasing\n",
        currentViewer, [currentViewer retainCount]);
    [currentViewer release];
    currentViewer = 0;

    currentViewer = newViewController;
    [currentViewer retain];

    [mainWindow addSubview:currentViewer.view];
    [mainWindow bringSubviewToFront:currentViewer.view];
}

При запуске кода я показываю, что текущий контроллер представления освобождается, а затем вызывается мой метод dealloc для этого контроллера представления. Но Инструменты / утечки все еще сообщают об этом как утечка. Например, я получаю эту распечатку:

Old viewController (0x119f80) has count of 1; now releasing
Deallocating WelcomeScreenViewController

Я могу проверить по адресу, что это тот же объект, который был выделен ранее.

Мой внешний код выглядит примерно так:

MyViewController *theViewController = [[MyViewController alloc]
                                        initWithNibName:nil
                                                 bundle:nil];
[GameMaster swapInNewView:theViewController];
[theViewController release];

У кого-нибудь есть предложения, как отследить, что происходит? Я использую 3.1.2 SDK, но я также видел это в более ранних SDK.

Ответы [ 2 ]

3 голосов
/ 18 ноября 2009

Ха. Это было весело. Я написал быстрый тест, чтобы убедиться, что ни один из нас не сошел с ума.

В конце концов, все сводится к вызывающему коду:

[[MyViewController alloc] initWithNibName:nil bundle:nil];

Когда вы инициализируете контроллер представления, его объект view еще не определен и не будет определен до тех пор, пока не будет запрошен.

Поскольку вы указываете nil для имени пера, вы должны переопределить loadView в своем подклассе UIViewController, чтобы правильно установить объект просмотра. Подробнее см. в документации Apple .

Реализация по умолчанию loadView, по-видимому, выполняет некую закулисную магию, и эта магия может привести к утечке памяти.

Итак: когда вы делаете этот звонок:

[mainWindow addSubview:currentViewer.view];

Вы на самом деле делаете два звонка:

One: currentViewer.view, что приводит к вызову [currentViewer loadView] и
Два: [mainWindow addSubview:...], который пытается добавить недавно загруженное представление.

Утечки идентифицируют эту строку из-за первого вызова, а не второго.

Чтобы проверить, просто измените метод loadView в ваших пользовательских UIViewController подклассах:

- (void)loadView
{
    [self setView:[[UIView new] autorelease]];
}

Это предотвращает вызов по умолчанию loadView, и теперь утечек больше нет.

Очевидно, что после дальнейшей разработки этого приложения вам придется либо добавить что-то более значимое в loadView, либо использовать nibs.

0 голосов
/ 18 ноября 2009

Обратите внимание на документацию для метода removeFromSuperview:

"Отсоединение получателя от его суперпредставления и его окна, удаление его из цепочки респондента и аннулирование прямоугольников курсора. Приемник также освобождается"

Я не уверен, если это ваша проблема или нет, но делаю:

[exampleViewController.view removeFromSuperview];
[exampleViewController release];

В моем приложении происходит задержка сбоя из-за чрезмерного освобождения объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...