swift UIGraphicsGetImageFromCurrentImageContext can't release memory

GSLiPt picture GSLiPt · Jun 23, 2015 · Viewed 7.8k times · Source

Swift Code

When we get a screenshot of a UIView, we use this code usually:

UIGraphicsBeginImageContextWithOptions(frame.size, false, scale)
drawViewHierarchyInRect(bounds, afterScreenUpdates: true)
var image:UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

Problem

drawViewHierarchyInRect && UIGraphicsGetImageFromCurrentImageContext will generate an image in current Context,but Memory will not released when when called UIGraphicsEndImageContext.

Memory using continues to increase until the app crashes.

Although there is a word UIGraphicsEndImageContext will call CGContextRelease automatically",it doesn't work.

How can I release the memory drawViewHierarchyInRect or UIGraphicsGetImageFromCurrentImageContext used

Or?

Is there anyway generating screenshot without drawViewHierarchyInRect?

Already tried

1 Auto release : not work

var image:UIImage?
autoreleasepool{
    UIGraphicsBeginImageContextWithOptions(frame.size, false, scale)
    drawViewHierarchyInRect(bounds, afterScreenUpdates: true)
    image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
}
image = nil

2 UnsafeMutablePointer : not work

var image:UnsafeMutablePointer<UIImage> = UnsafeMutablePointer.alloc(1)

autoreleasepool{
   UIGraphicsBeginImageContextWithOptions(frame.size, false, scale)
   drawViewHierarchyInRect(bounds, afterScreenUpdates: true)
   image.initialize(UIGraphicsGetImageFromCurrentImageContext())
   UIGraphicsEndImageContext()
}
image.destroy()
image.delloc(1)

Answer

Alex Black picture Alex Black · Apr 29, 2016

I solved this problem by putting image operations in another queue!

private func processImage(image: UIImage, size: CGSize, completion: (image: UIImage) -> Void) {
    dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0)) {
        UIGraphicsBeginImageContextWithOptions(size, true, 0)
        image.drawInRect(CGRect(origin: CGPoint.zero, size: size))
        let tempImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        completion(image: tempImage)
    }
}