Управление памятью при добавлении UIImageView в другое представление viewController из другого представления viewController - PullRequest
2 голосов
/ 08 марта 2011

Похоже, что в моем проекте нет утечек, и у меня есть много разделов, которые делают разные вещи.

Тем не менее, я обнаружил, что у меня есть некоторые проблемы с выделением ресурсов, доказанные мне меткой кучи в инструменте утечек, которые возникали большую часть времени при использовании iPad с внешним экраном. Приложение запрограммировано вести себя по-разному при подключении к внешнему экрану.

У меня есть масштабируемый раздел карты UIScrollView, в который я могу входить и выходить. При самостоятельном использовании iPad и проверке кучи меток рост кучи в конечном итоге снизится до 0 байт, и это хорошо. Однако при подключенном внешнем экране изображение отправляется на внешний экран, который использует другой контроллер представления, и проверка кучи меток при выходе из карты составляет примерно 6-7 МБ почти каждый раз без значительного уменьшения другой кучи наросты. BAD.

Что я обнаружил, так это то, что я совершенно не совсем правильно управляю выпуском внешнего UIImageView, и это было для меня очевидно, когда я просто посмотрел на него. Я объясню подробнее об этом чуть позже.

Важная вещь, прежде чем я продолжу объяснять, и я извиняюсь за то, что сделал это так долго, но я клянусь, я слышал, что есть исключение для того, чтобы не помещать объект alloc'd в dealloc, если он добавляется в другое представление из другого представления, потому что я не владею им, поэтому не несу ответственности за размен. Разбираюсь ли я в этом или нет, я получаю одинаковое поведение. Но я на самом деле не думаю, что когда-нибудь удастся избавиться от способа настройки моего кода. Поэтому я думаю, что моя проблема в том, что я не освобождаю вид изображения из памяти ... но остается вопрос, где мне это сделать в этом случае!

В методе initWithFrame представления A у меня добавлено представление на внешний экран, если он подключен:

    if(exScreenEnabled==1){
        mapImageViewEx = [[UIImageView alloc] init];

        CGPoint p = mapScrollView.contentOffset;
        mapImageViewEx.frame = CGRectMake((p.x*-1), (p.y*-1), mapImageView.frame.size.width, mapImageView.frame.size.height);

        NSString *mapExFileLocation = [[NSBundle mainBundle] pathForResource:[map_List objectAtIndex:mapNum] ofType:@"png"];
        NSData *mapExIMGData = [NSData dataWithContentsOfFile:mapExFileLocation];
        mapImageViewEx.image = [UIImage imageWithData:mapExIMGData];

        UIView *containerExViewP = (UIView*)[del.switchExVC.view viewWithTag:9000];

        [containerExViewP addSubview:mapImageViewEx];

    }

В методе viewDidLoad внешнего viewController добавлен контейнер, когда приложение запускается и пользователь выбирает разрешение экрана. Работая почти так же, как контроллер представления окна iPad, он предназначен для переключения между представлениями:

CGRect frame = CGRectMake(0, 0, 1024, 768);
containerExView = [[UIView alloc] initWithFrame:frame];
[containerExView setTag:9000];

self.view = containerExView;

Давайте просто назовем этот внешний viewController "View B"

Таким образом, это выглядит так, где начинается проблема: Когда пользователь нажимает кнопку «Назад», когда он находится на карте, если подключен внешний экран, представление A выполняет NSNotificationCenter, который прослушивает View B, чтобы удалить подпредставления в представлении B. контейнер. Вот метод в представлении B:

- (void)removeExView{
    [[self.view.subviews objectAtIndex:0] removeFromSuperview];
    NSLog(@"REMOVED EX VIEW");


    UIImage *idleExImage = [UIImage imageNamed:@"idle4.png"];
    UIImageView *idleExImageView = [[UIImageView alloc] initWithImage:(UIImage *)idleExImage];
    CGRect idleExFrame = CGRectMake(0, 0, 1024, 768);
    idleExImageView.frame = idleExFrame;
    [self.view addSubview:idleExImageView];

    [idleExImageView release];
}

Подвиды удаляются из контейнера View B с индексом 0, а затем отображается изображение по умолчанию.

Итак, я думаю, что хотя подпредставление было удалено, то есть представление изображения, оно не обязательно высвобождается из памяти. Но как бы вы получили доступ к этому? Это даже проблема? Возможно, он действительно должен быть решен, но никогда не достигнет этой точки, потому что представление неожиданно сначала удаляется. Я просто не знаю, потому что я еще не знаю, как правильно обращаться с этой ситуацией. Заранее благодарим за любую помощь, которую вы можете предоставить.

Ответы [ 2 ]

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

[containerExViewP addSubview: mapImageViewEx];

после этой строки используйте [containerExViewP release];

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

Сложно догадаться об этом, но я бы сказал, что эти строки

    mapImageViewEx = [[UIImageView alloc] init];
    // snipped some code for clarity
    [containerExViewP addSubview:mapImageViewEx];

    containerExView = [[UIView alloc] initWithFrame:frame];
    // snipped some code for clarity
    self.view = containerExView;

Они могут и должны быть освобождены после добавления в иерархию представлений

    [mapImageViewEx release];
    [containerExView release];

, если вы не намеренно сохраняете ссылку на них для чего-то, что не показано в фрагментах выше.

...