выпускать или не выпускать контроллер

#objective-c #ipad #release-management

#objective-c #iPad #выпуск-управление

Вопрос:

Прежде всего, извините за мой английский (я испанец) и за то, что я новичок. Я разрабатываю свое второе приложение для iPad для learnign, и у меня возникли проблемы с управлением памятью. Я сталкиваюсь с этой проблемой уже около месяца, поэтому я подумал, что, возможно, какой-нибудь эксперт в этом замечательном сообществе мог бы мне немного помочь.

Мой сценарий таков:

Это простое приложение для электронных книг. У меня есть главное представление, из которого пользователь может открыть два модальных представления. Основная проблема заключается в одном из модальных представлений. Там у меня есть scrollview, который управляет всеми страницами. На данный момент там 12 страниц. Я пытался освободить все и т.д., Но что-то остается в памяти, потому что в инструментах память продолжает расти, и когда я пропускаю модальное представление и возвращаюсь, через несколько раз происходит сбой. Страницы представляют собой отдельные xibs, и я загружаю их с помощью этого метода:

     - (void)loadScrollViewWithPage:(int)page {
if (page < 0) return;

if (page >= MyNumberOfPages) return;

if ((NSNull *)controller != [NSNull null]) {

    NSString *className = [NSString stringWithFormat:@"Pagina%d", page];
    Class myClass = NSClassFromString(className);

    controller = [[myClass alloc] initWithNibName:className bundle:nil];

// I have tried autorelease and even retain] autorelease.

           [viewControllers replaceObjectAtIndex:page withObject:controller];

    CGRect frame = scrollView.frame;
    frame.origin.x = frame.size.width * page;
    frame.origin.y = 0;
    controller.view.frame = frame;
    if (page != 0){
    controller.view.tag = page;
    }else {
        controller.view.tag = 9999;
    }

    [scrollView addSubview:controller.view];
    [scrollView sendSubviewToBack:controller.view];

            [controller release];


    }
}
  

Я загружаю по 3 страницы каждый раз, одну видимую, левую и правую. Я пытаюсь выгрузить (удалить или избавиться от) их таким образом (для тех, которые загружены около 3):

 [viewControllers removeObjectAtIndex:pagi - 2];
[[scrollView viewWithTag:pagi - 2] removeFromSuperview];
  

Итак, у меня две проблемы… Если я выпущу контроллер, как я делаю в описанном выше методе, мои IBActions на некоторых страницах приведут к сбою приложения. Но если я все равно его выпущу и удалю IBActions, объем памяти тоже продолжит расти. В инструментах он не показывает утечек, но он выходит из строя после увеличения объема памяти на 1 МБ или 2 МБ.

Я зарегистрировал все страницы viewDidUnload и deallocs, и они выгружаются только при появлении предупреждения о памяти.

Наконец, что для меня более странно, так это то, что если я не использую [выпуск контроллера]; приложения остаются дольше без сбоев. Но, конечно, они не освобождают.

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

Есть идеи?

Ответ №1:

Привет, Хорхе. Сначала я должен сказать, что ваш английский неплох. Я из Швейцарии, и если бы вы не сказали, что вы испанец, я бы этого не заметил. 😉

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

 [[myClass alloc] initWithNibName:className bundle:nil];
  

Итак, вы должны освободить его, потому что вы его выделили. Если вы используете alloc, сохраняете или копируете, вы несете ответственность за освобождение этих объектов.

Но я догадываюсь, в чем ваша проблема. Как вы определили controller ? Это iVar или также свойство? Если это свойство, у вас проблема с управлением памятью, потому что «старое» значение не освобождается. В этом случае используйте self.controller вместо controller .

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

Sandro Meier

Комментарии:

1. Большое тебе спасибо, Сандро. контроллер определяется в @interface как UIViewController *controller; но не @property.

2. В этом случае мой пример вам не поможет. ^^ Я не могу понять, почему он выходит из строя…

3. В любом случае любой ответ действительно полезен. Но даже если приведенный выше код верен, если я отпущу контроллер в этот момент, мои IBActions в загруженных nibs завершатся сбоем. Я читал, что это нормально, потому что я пытаюсь отправить действие объекту, который был освобожден, верно? Но … как я мог бы выпустить его и сохранить работу IBActions? Есть ли способ сделать это, или я просто прошу слишком многого?

4. Обычно [ViewControllers заменяет objectAtIndex:page на Object:controller] сохраняет объект, поскольку он используется в этом массиве. Поэтому странно, что ваш контроллер выпущен…

5. Спасибо, Сандро. То, что вы сказали о replaceObjectAtIndex, заставило меня заметить, что в некоторых моментах код был избыточным, но я думаю (как вы сказали), что ошибка не в этом методе. Теперь мое приложение выходит из строя только после длительной работы, поэтому я думаю, что это что-то «незначительное», но оно все еще там. Я продолжу поиски, и если найду решения, я опубликую их здесь.