renderincontext内存泄漏,如果不在主线程上使用
我想使用下面的代码将我的UIView转换成UIImage。
+ (UIImage *) imageWithView:(UIView *)view{ float scale = 1.0f; UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, scale); [view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage* img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); view.layer.contents = nil; return img; }
这个代码有两个问题。
1.当我在后台线程(!mainThread)中运行这个代码时,
在后台线程中调用renderInContext时遇到内存泄漏问题。
2.当我在主线程上运行这个代码
有没有内存泄漏,但在iPad 3我面临一些性能问题(我的用户界面挂起时调用此方法),同时从UIView创build图像。 因为我需要在一秒钟内将这个函数调用5次以上,所以UI挂起会给用户带来非常不好的体验。
请指导我,如果我在这里做错了什么?
我认为问题1与UIKit
不是线程安全的相关,它的使用会导致各种副作用。
如果你有像你所描述的性能问题,我看到的唯一path是在辅助线程上直接使用CoreGraphics(而不是UIKit)。
作为一个开始,你可以尝试这样的事情:
size_t width = view.bounds.size.width; size_t height = view.bounds.size.height; unsigned char *imageBuffer = (unsigned char *)malloc(width*height*4); CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef imageContext = CGBitmapContextCreate(imageBuffer, width, height, 8, width*4, colourSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little); CGColorSpaceRelease(colourSpace); [view.layer renderInContext:imageContext]; CGImageRef outputImage = CGBitmapContextCreateImage(imageContext); CGImageRelease(outputImage); CGContextRelease(imageContext); free(imageBuffer);
正如你所看到的,这比UIKit
方式要复杂得多,但它可以在辅助线程上运行(只要你find一种方法将outputImage
传递回你的UI线程,这个方法没有显示)。
我只是在主线程上发生了这种情况(内存泄漏,由于renderInContext
)。 我循环了数百个离屏视图,将它们渲染为UIImage
对象,并将它们保存为PNG文件。 什么解决了我的问题是包装我的循环在@autoreleasepool
块的胆量:
破碎:
for (...) { ...render layer in context... ...save image to disk... }
作品:
for (...) { @autoreleasepool { ...render layer in context... ...save image to disk... } }
有道理吧?