Как освободить viewController и его представление внутри NSMutableArray viewControllers? - PullRequest
1 голос
/ 30 марта 2011

У меня большая проблема с управлением памятью. На самом деле есть большой журнал, и каждая страница отображается с помощью собственного PageViewController. Мой код полностью основан на образце PageControl Apple Documentation, если вы когда-нибудь видели его.

Итак, в viewDidLoad моего "MainViewController" я создаю NSMutableArray = self.viewControllers, полный объектов NSNull. И я называю мой [self loadScrollViewPage:page]; для моей первой и второй страниц. Когда пользователь переходит на большее количество страниц, я вызываю (из scrollViewDidScroll) больше нагрузки [self loadScrollViewPage:nextPage];, так как приложению это понадобится. Также я внедряю unloadScrollViewPage:page, потому что журнал настолько большой, что памяти не будет, если я этого не сделаю.

Итак, это мой код:

- (void)loadScrollViewPage:(int)pageNumber
{
    if ((pageNumber < 0) || (pageNumber >= [self.viewControllers count]))
        return;

    PageViewController *controller = [self.viewControllers objectAtIndex:pageNumber];
    if ((NSNull *)controller == [NSNull null])
    {
        controller = [[PageViewController alloc] initWithPage:[self.pages objectAtIndex:pageNumber]];
        [self.viewControllers replaceObjectAtIndex:pageNumber withObject:controller];
        [controller release];
    }

    if (controller.view.superview == nil)
    {
        CGRect frame = mainpageScrollView.frame;
        frame.origin.x = 0;
        frame.origin.y = frame.size.height * pageNumber;
        controller.view.frame = frame;
        [mainpageScrollView addSubview:controller.view];
    }
}
- (void)unloadScrollViewPage:(int)pageNumber
{
    if ((pageNumber < 0) || (pageNumber >= [self.viewControllers count]))
        return;

    if ((NSNull *)[self.viewControllers objectAtIndex:pageNumber] != [NSNull null])
    {
        [[[self.viewControllers objectAtIndex:pageNumber] view] removeFromSuperview];
        [self.viewControllers removeObjectAtIndex:pageNumber];
        [self.viewControllers replaceObjectAtIndex:pageNumber withObject:[NSNull null]];
    }
}

Проблема в том, сколько бы раз я ни звонил unloadScrollViewPage, размер памяти все равно увеличивается, когда я звоню loadScrollViewPage, и никогда не уменьшается на unloadScrollViewPage. Итак, когда пользователь переходит на 10 страниц (из 300 страниц, смеется?), Объем памяти моего приложения составляет 100 МБ и, конечно же, происходит сбой: (* ​​1014 *

Мои вопросы:

  • Правильно ли я освобождаю память из моих self.viewControllers NSMutableArray?
  • Представления каждого контроллера, которые я надеваю, на их суперпредставление (представление MainViewController) будут освобождать его, когда я удаляюObjectAtIndex: pageNumber из self.viewControllers? Если нет, как я могу это сделать? Это моя проблема?

Спасибо заранее.

EDIT:

Похоже, Firoze Lafeer был в самом начале, проблема заключалась в том, что я управлял памятью UIImage, и мои взгляды сохранялись. Мне просто удается удалить из SuperView каждый UIView. Для изображений похоже на использование [UIImage imageNamed], он реализует кэш (который освобождает его, когда ios хочет ¬¬). Я просто изменил способ, используя [UIImage imageWithData:imageData];, который не реализует кеш, и все мои объекты теперь счастливы. Спасибо всем. :)

Ответы [ 2 ]

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

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

    [self.viewControllers removeObjectAtIndex:pageNumber];
    [self.viewControllers replaceObjectAtIndex:pageNumber withObject:[NSNull null]];

Первая строка будет удалять объект и уменьшать все индексывыше на один, так что ваш массив будет на один меньше.Затем вы вызываете replaceObject для объекта, который когда-то был на один индекс выше, чем объект, который вы удалили.Эти две строки кода будут уменьшать размер вашего массива на единицу каждый раз, когда он вызывается, пока вы не получите исключение за пределами границ, когда вы пройдете фактическую длину массива. Вы можете удалить строку removeObject и replaceObject освободит этот объект вон свой, оставляя ваш массив того же размера.

Это, вероятно, не решит вашу проблему, хотя и уменьшит счетчик хранения таким же образом.Возможно, это поможет опубликовать код, который вызывает эти методы.

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

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

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

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