Using CGContextDrawTiledImage at various scales leads to huge memory growth

I am working on an application where there is a view in a scalable UIScrollView. When the user zooms in or out, I redraw the view, which in UIScrollView should be beautiful and sharp. This view has a background image that I draw using CGContextDrawTiledImage.

I noticed that memory usage is increasing every time I switch to a new level of scaling. It seems that CGContextDrawTiledImage stores the cache somewhere in the image, scaled to different sizes. So, if I switch from 1.0 to 1.1 times, memory usage is increasing. A return to 1.0 does not lead to growth, but then a transition to 1.05, and then 1.2 leads to the fact that it will double. Back to 1.1 and no growth. Of course, the zoom level is under the control of the user, so I do not control how many zoom levels occur. Right now my background image is pretty massive (512x512), so this leads to a fast increase in memory usage. It does not appear as a memory leak in the Tools, but only additional allocations that are never freed.

I tried to find a way to free the cache, which seems to be created, but no luck. For example, it does not respond to low memory alerts.

I also tried setting the backgroundColor view to a UIColor created using colorWithPatternImage, but this does not work, because I am doing the scaling by changing the CTM graphics context, and not setting the view transform.

Any ideas on how to keep memory usage from exploding?

+3
source share
4 answers

, -, - CGImage , CTM. , , , , . , , .

Apple, .

0

, CGContextDrawTiledImage ( ) CTM?

0

? + imageNamed: iOS, + imageWithContentsOfFile: .

0

Based on Jacques answer, I found that I could clear the cache by simply making a copy CGImageRefand releasing the old one. Caches for other scales are not copied to the new link number.

I call it anywhere, I change the scale:

 /**
 * Switcheroo to persuade CGImage to drop the many megabytes of cache 
 * it creates when changing scale.
 */
- (void)discardRenderedImageCaches {
    CGImageRef newImageRef = CGImageCreateCopy(renderedImageRef);
    CGImageRef oldImageRef = renderedImageRef;
    renderedImageRef = newImageRef;
    CGImageRelease(oldImageRef);
}
0
source

Source: https://habr.com/ru/post/1769923/


All Articles