Вопрос

Цитировать из документа CGLayer:

  

Кварц кэширует любые объекты, которые используются повторно, включая объекты CGLayer.

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

Скажем ради простоты, что у меня есть куча UIImages, созданных в результате сетевого запроса, где-то сохраненных в массиве. Я создаю UIImageView примерно так:

anImage = [anArray objectAtIndex:0];
UIImageView* imgView = [[UIImageView alloc] initWithImage:anImage];
[mainView addSubview:imgView]; // Quartz eats memory for view after first draw
[imgView release];             // owned by mainView now
[...]                          // wait a bit for draw cycle
[imgView removeFromSuperview]; // memory doesn't go down

Когда imgView выходит за пределы экрана, он removeFromSuperview и освобождается. Хорошо верно? Нет, CGLayer, существующий в Quartz, не удаляется, потому что anImage все еще существует.

Как я могу обойти это? Единственный способ в этом сценарии - создать изображение точно так же за спиной Кварца с другим адресом указателя и удалить старое изображение. И единственный способ сделать это - «глубоко скопировать» изображение (UIImage не реализует NSCoding) или запросить его снова по сети (медленно).

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

Это было полезно?

Решение

Здесь вы увеличиваете imgView от 0 до 1.

UIImageView* imgView = [[UIImageView alloc] initWithImage:anImage];

В следующей строке mainView увеличивает счетчик ссылок. (сейчас 2)

[mainView addSubview:imgView]; // Quartz eats memory for view after first draw

Здесь вы выпускаете imgView, и счетчик ссылок возвращается к единице.

[imgView release]; // owned by mainView now

Я не думаю, что ваши проблемы с памятью имеют какое-либо отношение к anImage. Пока imgView является подпредставлением, оно не будет освобождать этот объект, потому что ему нужно, чтобы этот объект выводился на экран.

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

  

Кварц кэширует любые объекты, которые используются повторно, включая объекты CGLayer.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top