renderincontext内存泄漏,如果不在主线程上使用

Mad*_*oor 3 core-graphics objective-c uiimage ios

我试图使用下面的代码将我的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;
}
Run Code Online (Sandbox Code Playgroud)

这段代码有两个问题.

1.当我在后台线程中运行此代码时(!mainThread)

在后台线程中调用renderInContext时,我遇到了内存泄漏问题.

2.当我在主线程上运行此代码时

没有内存泄漏但是在iPad 3上我在从UIView创建图像时遇到了一些性能问题(当调用此方法时我的UI挂起).因为我需要在几秒钟内调用此函数超过5次,因此UI挂起会给用户带来非常糟糕的体验.

如果我在这里做错了什么,请指导我?

ser*_*gio 8

我认为问题1与UIKit不是线程安全的事实有关,它的使用会导致各种副作用.

如果您遇到性能问题,那么我看到的唯一前进方法是直接在辅助线程上使用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);
Run Code Online (Sandbox Code Playgroud)

如您所见,这比UIKit方式复杂得多,但它可以在辅助线程上运行(前提是您找到一种方法将outputImage后端传递给未显示的UI线程).

  • 要将图像翻转回正常,请在CGColorSpaceRelease之后添加这两行:`CGContextTranslateCTM(imageContext,0,height); CGContextScaleCTM(imageContext,1.0f,-1.0f);` (2认同)