Кварцевое кеширование CGLayer - PullRequest
1 голос
/ 30 июля 2009

Цитировать из документа 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 и освобождается. Хорошо верно? Нет, CGLayer, существующий в Quartz, не удаляется, потому что anImage все еще существует.

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

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

1 Ответ

1 голос
/ 31 июля 2009

Здесь вы увеличиваете 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.

...