views:

500

answers:

1

To quote from the CGLayer doc:

Quartz caches any objects that are reused, including CGLayer objects.

I am having problems with memory on large pages and am trying to implement a simple mechanism where views are released and recreated based on whether they are on/off screen.

Say for the sake of simplicity that I have a bunch of UIImages, created as the result of a network request, saved in an array somewhere. I create a UIImageView like so:

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

When the imgView goes offscreen it is removedFromSuperview and released. Fine right? Nope- the CGLayer that exists in Quartz is not removed, because anImage still exists.

How can I get around this? The only way in this scenario is to create an image exactly the same behind Quartz's back with a different pointer address and delete the old image. And the only way to do this is to 'deep copy' the image (UIImage doesn't implement NSCoding) or to ask for it again over the network (slow).

What I am thinking is that I need to sqllite my images to a database and refetch them every time a view comes onscreen- but I would love to hear people's thoughts on this.

A: 

Here you increment imgView from 0 to 1.

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

In the next line, the mainView incrementes the reference count. (now it's 2)

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

Here, you release the imgView and the reference count goes back down to one.

[imgView release]; // owned by mainView now

I don't think your memory issues have anything to do with anImage. As long as imgView is a subview, it won't free that object, because it needs that object to draw to the screen.

What the following line means, is that if you programmatically draw to your CGLayer, Quartz with cache what you've drawn, so that you aren't constantly redrawing the same thing. It's not really related to adding subViews.

Quartz caches any objects that are reused, including CGLayer objects.

Kailoa Kadano
Thanks for the response. I made a mistake when simplifying for my example (edited now), but the UIView definitely does get released. I have done extensive testing with this. Memory will never get released until the UIImage itself is released.
Sam