简体   繁体   中英

Memory leak when resizing UIImage

I've read through multiple threads concerning the topic but my problem still persists. When I'm resizing an Image with following code:

extension UIImage {
  func thumbnailWithMaxSize(image:UIImage, maxSize: CGFloat) -> UIImage {
    let width = image.size.width
    let height = image.size.height
    var sizeX: CGFloat = 0
    var sizeY: CGFloat = 0
    if width > height {
        sizeX = maxSize
        sizeY = maxSize * height/width
    }
    else {
        sizeY = maxSize
        sizeX = maxSize * width/height
    }

    UIGraphicsBeginImageContext(CGSize(width: sizeX, height: sizeY))
    let rect = CGRect(x: 0.0, y: 0.0, width: sizeX, height: sizeY)
    UIGraphicsBeginImageContext(rect.size)
    draw(in: rect)
    let thumbnail = UIGraphicsGetImageFromCurrentImageContext()!;

    UIGraphicsEndImageContext()

    return thumbnail

}


override func viewDidLoad() {
    super.viewDidLoad()

    let lionImage = UIImage(named: "lion.jpg")!

    var thumb = UIImage()

    autoreleasepool {
        thumb = lionImage.thumbnailWithMaxSize(image: lionImage, maxSize: 2000)
    }
    myImageView.image = thumb
}

...the memory is not released. So when I navigate through multiple ViewControllers (eg with a PageViewController) I end up getting memory warnings and the app eventually crashes. I also tried to load the image via UIImage(contentsOfFile: path) without success. Any suggestions?

I noticed your code beginning two contexts but only ending one.

Here's my extension, which is basically the same as your's. Since I'm not having memory issues, it looks like that may be the issue.

extension UIImage {
    public func resizeToRect(_ size : CGSize) -> UIImage {
        UIGraphicsBeginImageContext(size)
        self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext();
        return resizedImage!
    }
}

The problem is this:

UIGraphicsGetImageFromCurrentImageContext() returns an autoreleased UIImage. The autorelease pool holds on to this image until your code returns control to the runloop, which you do not do for a long time. To solve this problem, make thumb = nil after using it.

var thumb = UIImage()

autoreleasepool {
   thumb = lionImage.thumbnailWithMaxSize(image: lionImage, maxSize: 2000)
   let myImage:UIImage = UIImage(UIImagePNGRepresentation(thumb));
   thumb = nil
}
myImageView.image = myImage

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM