NSCache removes all its data when app goes to background State

江枫思渺然 提交于 2020-05-27 05:40:40

问题


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;
            });
        });
    }

回答1:


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
}


来源:https://stackoverflow.com/questions/20606161/nscache-removes-all-its-data-when-app-goes-to-background-state

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!