在循环中释放renderInContext结果

时间:2011-02-11 15:11:52

标签: iphone memory quartz-graphics

我有一个在循环中调用的方法,看起来像这样:

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;

然而,根据Instruments Memory Monitor的说法,内存使用量会不断增加,直到循环结束才会出现故障。 (它崩溃了。)

如果我将UIGraphicsBeginImageContext替换为UIGraphicsEndImageContext

UIImage * image = someotherimage;

然后内存不会出现峰值,但是在循环的每次迭代中都会被分配并减少,正如我所期望的那样,由于自动释放池。 (它没有崩溃)

如果我只是注释掉renderInContext行,它可以正常工作。 (不会崩溃)

所以看起来好像renderInContext以某种方式保留在图像上 - 我怎样才能让它释放它?或者任何其他建议请:)?

2 个答案:

答案 0 :(得分:15)

当然,在经过3天的实验后,我会在一小时内找到答案(答案,无论如何,我很乐意对此发表评论)。

我添加

background.layer.contents = nil;

UIGraphicsEndImageContext();

并且未缓存图层中的缓存内存:)。

答案 1 :(得分:-1)

我没有使用UIImageView,因此设置layer.contents = nil对我不起作用。但是,我找到了一个不同的解决方案,虽然不理想,但确实有效。似乎renderInContext分配的内存在main_queue空闲之前不会被释放。所以,我做了以下几点:

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();
                ...
            }
        }
    }
}

这解决了我的记忆问题。我没有处理很多图片,所以我不知道如何影响性能。