Can memory in my code be better managed when using

2019-08-24 21:11发布

问题:

I'm declaring some UIImage arrays:

var animationImages1: [UIImage] = []
var animationImages2: [UIImage] = []

I'm using a background thread to load the images:

DispatchQueue.global(qos: .background).async { () -> Void in

self.animationImages1 = self.createImageArray(total: 57, imagePrefix: "animation1")
self.animationImages2 = self.createImageArray(total: 42, imagePrefix: "animation2")

}

The function called above:

var imageArray: [UIImage] = []

for imageCount in 1..<total {
     var imageName = String(format: "\(imagePrefix)\(imageCount)")

     let image = UIImage(contentsOfFile: Bundle.main.path(forResource: imageName, ofType: "png")!)!
     //let image = UIImage(named: imageName)!

     imageArray.append(image)
}

return imageArray

Then when I want to animate, I'm calling this function:

func animate(imageView: UIImageView, images: [UIImage], duration: TimeInterval) {
     imageView.animationImages = images
     imageView.animationDuration = duration
     imageView.animationRepeatCount = 1
     imageView.startAnimating()
}

I tried doing both theImageView.stopAnimating() and theImageView.animationImages = nil before calling the animation again but didn't notice any improvement to memory management using either.

With UIImage(named:) the images visible in the app start disappearing either partially or completely as memory runs low. With UIImage(contentsOfFile:) the app promptly crashes once memory runs low.

To note: I tried UIImage(named:) with the images in the Assets catalog, and then switched to UIImage(contentsOfFile:) with the images dragged in to the project outside of Assets.xcassets

Is it possible to use this function of UIImageView for longer animations (2-5 seconds: 40-150 pngs) with a file size of about 450k each, or is it too much a memory strain regardless of how you go about it?

It currently runs without an issue on a newer iPad Pro, and using Xcode's simulator it runs well (but eats a lot of memory) on all device sizes. On an iPhone X and an iPhone 8 Plus, it runs out of memory pretty early on - after playing through 5 to 10 animations or so.

Am I missing something, is it not possible, or do I need to do further research on ways to keep memory in check while running these large UIImage arrays through startAnimating()?

Memory usage is not going down. I must be caching this somewhere...

Thanks for any help!

回答1:

I created a new Xcode project simplified to focus just on this issue, and was given a correct answer by @Stephan Schlecht here.

Although the memory hit doesn't occur when assigning the images to an array, and the memory hit only happens once the animation is played, still the only way to reclaim the memory seems to be removing all references to the image array by setting both the variable array and the animationImages property on the UIImageView to a blank array.

So in the particular example given in this question:

animationImages1 = []
imageView.animationImages = []