Last Updated: September 27, 2021
·
5.946K
· voidet

UIImageView+AFNetworking & NSCache a Warning from Warnings

Recently I found some out of memory warnings occurring within my application. Not seeing any retain cycles from my namespace or ui elements I had to start looking a bit deeper. At first I saw a virtual memory heap increasing quite rapidly, without ever going down.I figured this had to be some internal memory management scheme that was ready to burst and it was out of my control. Wrong.

I am using UIImageView+AFNetworking, which if you are unfamiliar, will take an image URL and a placeholder URL, fetch the image whilst displaying a placeholder in the mean time. This is backed by NSCache so that if you request the same image at a later date, then the image will be dug up from cache, in memory....

How I started looking at UIImageView+AFNetworking was through the profiling tool, watching "CG Raster Data" objects increasing. I could identify some larger objects, of which were bitmap objects created from AFNetworking's image responses. These images were being drawn using CGContext's and being release properly, so why were they still around. Quickly looking through the code a bit more NSCache popped up, without an upper bounds. It was caching all and every one of our objects for as long as it saw fit! So I built in an upper limit and a hook for us to clear the cache:

+ (AFImageCache *)af_sharedImageCache {
    static AFImageCache *_af_imageCache = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _af_imageCache = [[AFImageCache alloc] init];
        [_af_imageCache setCountLimit:1000];
    });

    return _af_imageCache;
}

+ (void)clearCachedImages {
    [[[self class] af_sharedImageCache] removeAllObjects];
}

Now when I'm sure I'm ready to discard the cached images I just call [UIImageView clearCachedImages]. That or they'll automatically be cleared once the cache object count limit gets hit. That's 2 hours of my life I won't get back!

2 Responses
Add your response

I think this is a better solution when you are not worried about having memory warnings but worried of not handling them right.
http://stackoverflow.com/a/21540454/1130894

With this you don't set any limit (which could be specific to your app or a set of content) but instead improve the behaviour for when you get a memory warning.

over 1 year ago ·

That's awesome thanks a lot banaslee. I will look into that today as I think it is better to tap into the memory warnings in iOS than to set an arbitrary number of max cache objects.

over 1 year ago ·