UIImageView is caching all of my images causing memory issues

I'm using a UIImageView to display album artwork when playing music. Every time new artwork is loaded, the memory usage increases. I'm using ARC and tried a autoreleasepool around the code. If I put the app in the background, the cache clears and it starts using up memory again.

Here's my code:

- (void) showArtwork {
    @autoreleasepool {
        MPMediaItem *currentItem = [self.musicPlayer nowPlayingItem];
        if (currentItem) {
            MPMediaItemArtwork *artwork = [currentItem valueForProperty: MPMediaItemPropertyArtwork];
            if (artwork) {
                UIImage *artworkImage = [artwork imageWithSize: CGSizeMake (339, 339)];
                if (artworkImage) {
                    [self.appCoverArt setImage: artworkImage];
                }
            }
        }
    }
}

musicPlayer is the systemMusicPlayer
appCoverArt is my UIIMageView

1. Is there a way to release an image from UIImageView before assigning a new image?
2. Is there a way to clear the pool other than putting the app in the background (which does clear the memory)?
Answered by Engineer in 790018022

With ARC, you release an image from UIImageView by setting its image property to nil, or to another instance of UIImage, provided the retain count of the previous UIImage drops to zero.

Based on the code you shared, it is unlikely that the memory buildup is being caused by setting a new image on the appCoverArt variable. Perhaps memory is being retained elsewhere, such as a variable that holds the player's queue?

A great way to find out how memory is being retained is to run Instruments' Allocations tool. Please see Gathering information about memory use and Minimizing your app's Memory Footprint for detailed information.

I should also mention that showArtwork is only called when the app gets a notification that the playback item has changed.

With ARC, you release an image from UIImageView by setting its image property to nil, or to another instance of UIImage, provided the retain count of the previous UIImage drops to zero.

Based on the code you shared, it is unlikely that the memory buildup is being caused by setting a new image on the appCoverArt variable. Perhaps memory is being retained elsewhere, such as a variable that holds the player's queue?

A great way to find out how memory is being retained is to run Instruments' Allocations tool. Please see Gathering information about memory use and Minimizing your app's Memory Footprint for detailed information.

The player's queue isn't changing - I load one playlist of songs and as it plays through them I watch memory increase until it's played the last song in the queue. Once it's displayed all of the images once, memory stops growing so it is definitely the UIImages that are being cached. My concern is that a user may select a large playlist which will cause the system to run out of memory. Since it is a one view app it won't get a chance to garbage collect until they go to another app. Any way I can force it to release or clear the cache?

I commented out the line where the UIImageView is set and memory still grows. If I comment out this line memory doesn't grow: UIImage *artworkImage = [artwork imageWithSize: CGSizeMake (339, 339)]; I even set artworkImage to nil after assigning it to the image view and memory still grows. How do I release artworkImage?

I ran the allocations tools and there are no leaks in my code. However, the memory usage continues to increase as new images are loaded. Nothing I've tried other than manually sending the app to the background clears the memory. The UIImage imageWithSize seems to be the guilty party but even setting that variable to null doesn't clear the memory used. I also found someone else with the same issue: https://stackoverflow.com/questions/40029628/mpmediaitemartwork-imagewithsize-memory-leak

UIImageView is caching all of my images causing memory issues
 
 
Q