2009-07-30 7 views
1

Цитата из док CGLayer:Кварц кэширование 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 идет закадровый это removedFromSuperview и отпускают. Хорошо? Nope - CGLayer, который существует в Quartz, не удаляется, потому что anImage все еще существует.

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

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

ответ

1

Здесь приращение imgView от 0 до 1.

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

В следующей строке MainView incrementes счетчик ссылок. (теперь это 2)

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

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

[imgView release]; // owned by mainView now 

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

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

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

+0

Благодарим за отзыв. Я допустил ошибку, когда упростил мой пример (теперь отредактирован), но UIView определенно освобождается. Я провел обширное тестирование с этим. Память никогда не будет выпущена до выпуска UIImage. – Sam