内存泄漏与renderInContext和UIImagePNGRepresentation

时间:2015-10-31 23:46:02

标签: ios swift memory-leaks core-graphics

我在通过将不可见的视图渲染到上下文中来创建图像时发现大量内存泄漏。我已将其缩减为最基本的实现,并确定了导致内存泄漏的两行代码:renderInContextUIImagePNGRepresentation。如果我同时注释掉,则不会发生泄漏,但如果其中一个未被注释,则会发生泄漏,如果两个都未被注释,则会发生两次泄漏。 每次调用下面的方法时,内存使用量会显着增加(如预期的那样),然后片刻之后会减少,但比调用之前的数量高出0.8 MB。

如何解决此问题以确保没有内存泄漏?

public class func imageDataForSymbol(symbol: String) -> NSData? {
    var imageData: NSData!

    let dimension = 180

    let label = UILabel(frame: CGRectMake(0, 0, CGFloat(dimension), CGFloat(dimension)))
    label.text = symbol

    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let bitmapInfo = CGImageAlphaInfo.PremultipliedLast.rawValue
    let bitmapContext = CGBitmapContextCreate(nil, dimension, dimension, 8, 0, colorSpace, bitmapInfo)!

    label.layer.renderInContext(bitmapContext) //FIXME: causing leak!!

    let cgImage = CGBitmapContextCreateImage(bitmapContext)!
    let image = UIImage(CGImage: cgImage)
    imageData = UIImagePNGRepresentation(image)! //FIXME: causing leak!!

    return imageData
}

要在viewDidAppear

中对其进行测试
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
        NSData *d = [ImageGenerator imageDataForSymbol:@"W"];

        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"triggered");
        });
    });
});

如果有更好的方法可以为NSData UILabel的图片创建layer,我会全力以赴。除了从CIImage然后从CGImageCIImage然后从UIImage到{创建UIImage之外,我无法想到获得它的另一种方式{1}}。请注意,它不需要很快,但它需要在后台线程上创建图像,以确保UI保持对其他输入的响应。

1 个答案:

答案 0 :(得分:-1)

将CGColorSpaceCreateDeviceRGB与CGColorSpaceRelease配对

使用CGContextRelease

对CGBitmapContextCreate进行配对

使用CGContextRelease配对CGBitmapContextCreateImage