Freeing renderInContext result in a loop

I have a method that is called in a loop that looks something like this:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; UIImageView *background = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, PAGE_WIDTH, PAGE_HEIGHT)]; background.image = backgroundImg; for (UIView *view in viewArray) { [background addSubview:view]; } UIGraphicsBeginImageContext(background.frame.size); [background.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); for (UIView *view in background.subviews) [view removeFromSuperview]; background.image = nil; [background release]; [image retain]; [pool drain]; [image autorelease]; return image; 

However, according to the Memory Memory Monitor, memory usage increases and increases and never goes down to the end of the cycle. (Failure.)

If I replaced UIGraphicsBeginImageContext with UIGraphicsEndImageContext using

UIImage * image = someotherimage;

then the memory does not burst, but is allocated and reduced at each iteration of the loop, as expected, due to the Autorelease pool. (This is not a glitch)

And if I just comment out the renderInContext line, it works fine. (Not crashing)

So it seems that renderInContext is somehow holding onto an image - how can I free it? Or any alternative suggestions please :)?

+7
source share
2 answers

Naturally, after 3 days of experiments, I find the answer (the answer, in any case, and I would be glad to comment about it) within an hour.

I add

 background.layer.contents = nil; 

after

 UIGraphicsEndImageContext(); 

and the cached memory in the layer does not decompose :).

+14
source

I do not use UIImageView, so setting layer.contents = nil did not work for me. However, I found another solution that, although not perfect, works. It seems that the memory allocated by renderInContext is not freed until main_queue is working. So, I did the following:

 dispatch_queue_t queue = dispatch_queue_create("com.example.imageprocessing", DISPATCH_QUEUE_SERIAL); for (int k = 0; k < images.count; ++k) { dispatch_async(queue, ^{ dispatch_sync(dispatch_get_main_queue(), ^{ @autoreleasepool { ... UIGraphicsBeginImageContext(self.view.bounds.size); [view.layer renderInContext:UIGraphicsGetCurrentContext()]; image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); ... } } } } 

This solved the problem with my memory. I do not process a lot of images, so I do not know how performance affects.

-one
source

All Articles