I've written a little iOS app which creates a slideshow based on images stored in the Documents directory (under Files).
It works but I think it's leaking memory. The reason I say this is because when running it, I see the memory creeping up in XCode each time an image is replaced.
It's not very complicated. I have:
override func viewDidLoad() {
super.viewDidLoad()
self.imageView.contentMode = .scaleAspectFill
self.imageView.frame = CGRect(
x: 0,
y: 0,
width: self.bounds.size.width,
height: self.bounds.size.height
)
view.addSubview(self.imageView)
/* Loads the filenames of the images */
loadImages()
displayNext()
Timer.scheduledTimer(
timeInterval: self.cycleSeconds,
target: self,
selector: #selector(displayNext),
userInfo: nil,
repeats: true
)
}
@objc
func displayNext() {
let imageURL = self.documentsURL.appendingPathComponent(self.imageNames[self.imageIndices[self.i]])
replaceImage(with: imageURL)
if self.i + 1 == self.imageNames.count {
shuffleImageIndices()
self.i = 0
} else {
self.i = self.i + 1
}
}
The code displayNext()
eventually calls this code below to transition to the next image:
func replaceImage(with imageURL: URL) {
assert(imageURL.isFileURL)
let nextImage = UIImage(named: imageURL.path)
UIView.transition(
with: self.imageView,
duration: 0.1,
options: .transitionCrossDissolve,
animations: { self.imageView.image = nextImage },
completion: nil
)
}
Somehow all this leaks memory and I can't seem to figure out how to get rid of it.
The Image(named:)
caches images. So you are most likely seeing a memory increase as a result of memory consumption of the cache. Check the documentation.
You should use the constructor as UIImage(contentsOfFile:)
.
Discussion:
There is nothing wrong with using cached version. The images will be cached which improves performance but may consume more memory. This is not a memory leak but an expected behaviour. The cache itself will not crash your app due to memory consumption, it will purge the cache when a lot of memory is being used by it and memory consumption will drop.