I'm seeing a large memory leak when creating images by rendering a non-visible view into a context. I've reduced it down to the most basic implementation and have determined two lines of code that are contributing to the memory leak: renderInContext
and UIImagePNGRepresentation
. If I comment both out, no leak occurs, but if one of them is uncommented a leak occurs, if both are uncommented two leaks occur. Each time the method below in invoked, memory usage increases significantly (as expected), then after a moment it decreases but is ~0.8 MB higher than the amount it was before the invocation.
How can I resolve this to ensure there are no memory leaks?
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
}
To test it, in 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");
});
});
});
If there is a better way to create NSData
for an image of a UILabel
's layer
, I'm all for it. I could not think of a different way to obtain it though, other than creating a CIImage
from CGImage
then from CIImage
to UIImage
then from UIImage
to NSData
. Note that it doesn't need to be fast, but it does need to create the image on a background thread to ensure the UI remains responsive to additional input.