#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, заставило меня заметить, что в некоторых моментах код был избыточным, но я думаю (как вы сказали), что ошибка не в этом методе. Теперь мое приложение выходит из строя только после длительной работы, поэтому я думаю, что это что-то «незначительное», но оно все еще там. Я продолжу поиски, и если найду решения, я опубликую их здесь.