I have a UICollectionView
with 4 cells
in a grid pattern and no scrolling
. Each cell has a single imageView
. The images
are stored in the asset folder and retrieved by name reference (see below). After some UI
action, the idea is to
collectionView.reloadData()
and replace the image
in each cell
.
Everything works fine, but the memory use keeps climbing
after each reload. I had assumed reloadData()
dumps unnecessary
data
, but this experience has me puzzled. What's happening?
If it helps, I read somewhere loading an image with
UIImage(name: ...)
caches the image. I've tried to confirm this but have drawn a blank.
My code is pretty straightforward so I'm wondering if this is some memory bug / feature for scrolling purposes (that I don't want).
Once again, I'm looking to stop the memory stockpiling. Any ideas?
I never had the chance to understand when the image cache is evicted.
Collection view cell are dequeued and reused. That means than right after a cell goes out of screen is put in a recycle bin, if the cell is need again is taken from that recycle bin and placed into you views hierarchy (this is called flyweight pattern I guess), basically you are saving the instantiation cost.
Thus when you deal with images and your images are not stored elsewhere in memory but just inside the image view, every time a cell is shown and an new image is passed to the image view the old image should be freed.
This could not happen if you store a reference to the old image elsewhere, for instance a cache or an array.
To load image from xcasset you can only use UIImage(name: ...)
that means the image will be cached. Even if Apple says that this cache will be evicted in memory pressure situations and never seen this happening "in time" to avoid the app crashing.
What you can do is do not save in the xcasset folder, but anywhere in your project, in this way they will be loaded into your main bundle, you can load images from here by using the common:
let path = NSBundle.mainBundle().pathForResource(<#T##name: String?##String?#>, ofType: <#T##String?#>)
let image = UIImage(contentsOfFile: path!)
Pay attention that path is an optional.
As a general rule, always try to save resources by using image of the same view size in pixel, the occupied space of an image means nothing, just how its compressed, when loaded in memory it takes n_pixel_height * n_pixel_width * n_channels
bytes
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With