UIViews, связанные с утечками памяти

Мой графический интерфейс для приложения для iPhone использует множество UIView. Пользователь "листает" эти представления, когда нажимает кнопку для перехода вперед или назад. Представления хранятся за пределами экрана и добавляются к фактическому представлению только тогда, когда программе необходимо его отобразить.

Во время процесса переворота программа сообщает родительскому представлению (uiscrollview) удалить любое существующее подпредставление с помощью метода removeFromSuperView, а затем добавляет новое подпредставление, которое является новой страницей, которую должен увидеть пользователь.

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

Я попытался диагностировать эту проблему с помощью инструмента Leaks, но безуспешно. Есть только 1 или 2 небольшие утечки памяти, а общее использование памяти на устройстве программой составляет всего 2,5 МБ. Возможно ли, что не хватает видеопамяти, а не системной?

Я наткнулся на это сообщение об использовании backgroundColor и памяти. , но мне нужны дополнительные объяснения. Должен ли я уменьшить настройку backgroundColor, чтобы CALayer UIView не занимал слишком много памяти?


person obsoleteModel81    schedule 14.08.2009    source источник


Ответы (2)


Где вы храните все эти просмотры? В частности, есть ли у вас какой-нибудь массив (NSArray), который имеет эти представления, когда вы их пролистываете?

Представления не будут освобождены, если их счетчик ссылок не станет равным нулю. Ваш `[[UIView alloc] init] делает счетчик ссылок равным 1, добавление его в качестве подпредставления делает его 2, а удаление его из подпредставления делает его снова равным 1. Поскольку вам не сообщают о конкретной утечке, кажется, что вы действительно не протекаете, а храните ее где-то.

person Itay    schedule 14.08.2009
comment
Да, я использую NSArray для хранения этих представлений за пределами экрана. В целом они не занимают так много памяти, но проблема с памятью возникает после того, как я периодически добавляю и удаляю UIViews из основного ScrollView. Следует также отметить, что если я пролистываю между 2-3 одними и теми же экземплярами представления, ничего не происходит, и все работает нормально. Однако, если я пролистаю 10 или более просмотров, программа выйдет из строя. Такое ощущение, что я почти справился с этой проблемой. - person obsoleteModel81; 14.08.2009
comment
Трудно сказать, не зная точно, что ты делаешь. Итак, две вещи: 1. Добавьте код, показывающий, что вы делаете в своем вопросе, чтобы мы могли лучше вам помочь. 2. Я предполагаю, что вы добавляете просмотры по запросу в эту область, и по мере того, как вы просматриваете более уникальные представления (то есть те, которые вы не видели раньше), вы используете все больше и больше памяти. Попробуйте сделать следующее: в том же месте, где вы вызываете removeFromSuperview, также вызовите [yourArray removeObject:view];. Если это решит вашу проблему, мы знаем, в чем проблема, и можем предложить чистое / подходящее решение. - person Itay; 14.08.2009
comment
Похоже, удаление представления из кеша после его отображения предотвратило возникновение проблемы с памятью. Во-первых, важно отметить, что все представления были инициализированы до любого рендеринга. Однако, хотя проблемы с памятью больше нет, поскольку представления освобождаются после удаления из прокрутки, у программы больше нет возможности вернуться на страницу. (Это может быть только страница вперед). Является ли инициализация компонентов представления в реальном времени лучшим вариантом или есть альтернативное решение? - person obsoleteModel81; 14.08.2009
comment
Без кода сказать почти невозможно. Как правило, вам не следует держать виды, если вы их не показываете. Вместо этого сохраните достаточно состояния, чтобы воскресить их, а затем просто создайте новое представление. Поэтому, если кто-то пытается вернуться на страницу из представления X, вам необходимо загрузить представление X-1. Наконец, чтобы избежать времени загрузки / мерцания, если пользователь хочет видеть представление X, вы должны предварительно загрузить представления X-1 и X + 1. Таким образом, вы всегда будете на один взгляд впереди. Если вы опубликуете пример кода того, что вы делаете, я смогу дать более конкретный совет. - person Itay; 14.08.2009
comment
Это предложение решило мою проблему. Я просто храню модели в массиве вместо фактических представлений. Сначала я думал, что накладные расходы на рендеринг представлений сразу слишком высоки, но на самом деле это не так. - person obsoleteModel81; 15.08.2009

У вас есть доступ к образцу кода iphone на Apple? Похоже, программа PageControl Sample Code - хороший пример того, что вы ищете. И в программах с примерами кода нет утечек памяти или подобных проблем :) Ссылка здесь

Когда вы использовали инструменты, вы проверяли ObjectAllocations? Я обнаружил, что это более полезно, чем инструмент утечек (хотя одним из инструментов, который включает утечка, является выделение объектов). Я бы подумал, что если бы видеопамять была на исходе, это была бы другая ошибка, но могу ошибаться.

person kiyoshi    schedule 14.08.2009
comment
У Киёси определенно есть правильная идея и правильная ссылка. Методы, о которых я говорю, упоминаются в примере PageControl, но они не полные - вам все равно придется удалить неиспользуемые подпредставления. - person Itay; 14.08.2009