我在通过将不可见的视图渲染到上下文中来创建图像时发现大量内存泄漏。我已将其缩减为最基本的实现,并确定了导致内存泄漏的两行代码:renderInContext
和UIImagePNGRepresentation
。如果我同时注释掉,则不会发生泄漏,但如果其中一个未被注释,则会发生泄漏,如果两个都未被注释,则会发生两次泄漏。 每次调用下面的方法时,内存使用量会显着增加(如预期的那样),然后片刻之后会减少,但比调用之前的数量高出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
然后从CGImage
到CIImage
然后从UIImage
到{创建UIImage
之外,我无法想到获得它的另一种方式{1}}。请注意,它不需要很快,但它需要在后台线程上创建图像,以确保UI保持对其他输入的响应。
答案 0 :(得分:-1)
将CGColorSpaceCreateDeviceRGB与CGColorSpaceRelease配对
使用CGContextRelease
对CGBitmapContextCreate进行配对使用CGContextRelease配对CGBitmapContextCreateImage