I am working with NSCache
, I am using NSCache
to store images. I am showing images on UITableView
. Whenever I add images first they are resized and then added to the table and then to NSCache
. eveything works fine.
But whenever app goes to background when I close the app and open again, My Cache will be empty and again my app resizes images and then show it, because of which at first I see a empty table.
I am not understanding why this is happening. Is this the intended behaviour of NSCache
? .If yes then how can we improve the user experience so that use doesnt see the lag.
here is my code which was suggested to me by @ipmcc
Here category is my entity name (I am using coreData)
// A shared (i.e. global, but scoped to this function) cache
static NSCache* imageCache = nil;
// The following initializes the cache once, and only once
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
imageCache = [[NSCache alloc] init];
});
// Generate a cache key sufficient to uniquely identify the image we're looking for
NSString* cacheKey = [NSString stringWithFormat: @"%@", category.name];
// Try fetching any existing image for that key from the cache.
UIImage* img = [imageCache objectForKey: cacheKey];
self.imageView.image = img;
// If we don't find a pre-existing one, create one
if (!img)
{
// Your original code for creating a resized image...
UIImage *image1 = [UIImage imageWithData:category.noteImage];
CGSize newSize;
if(image1.size.width == 1080 && image1.size.height == 400)
{
newSize = CGSizeMake(300, 111);
}
dispatch_async(dispatch_get_global_queue(0,0), ^{
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image1 drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
dispatch_async(dispatch_get_main_queue(), ^{
// Now add the newly-created image to the cache
[imageCache setObject: newImage forKey: cacheKey];
self.imageView.image = newImage;
});
});
}
Yes it does that, for some reason it instantly removes data from cache when app enters background even if there is no memory pressure. To fix this you have to tell NSCache
that your data should not be discarded.
Here is how you fix this.
class ImageCache: NSObject , NSDiscardableContent {
public var image: UIImage!
func beginContentAccess() -> Bool {
return true
}
func endContentAccess() {
}
func discardContentIfPossible() {
}
func isContentDiscarded() -> Bool {
return false
}
}
and then use this class in NSCache
like this.
let cache = NSCache<NSString, ImageCache>()
and then set the data in cache like this
let cacheImage = ImageCache()
cacheImage.image = imageDownloaded
self.cache.setObject(cacheImage, forKey: "somekey" as NSString)
and to retrive the data
if let cachedVersion = cache.object(forKey: "somekey") {
youImageView.image = cachedVersion.image
}
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