本文介绍了当应用程序进入后台状态时,NSCache 删除其所有数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 NSCache,我正在使用 NSCache 来存储图像.我在 UITableView 上显示图像.每当我首先添加图像时,它们都会调整大小,然后添加到表中,然后添加到 NSCache.一切正常.

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.

我不明白为什么会发生这种情况.这是 NSCache 的预期行为吗?.如果是,那么我们如何改善用户体验,使使用不会出现延迟.

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.

这是@ipmcc 向我建议的代码

here is my code which was suggested to me by @ipmcc

这里的类别是我的实体名称(我使用的是 coreData)

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

推荐答案

是的,它会这样做,出于某种原因,即使没有内存压力,它也会在应用程序进入后台时立即从缓存中删除数据.为了解决这个问题,你必须告诉 NSCache 你的数据不应该被丢弃.

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

然后像这样在 NSCache 中使用这个类.

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)

并检索数据

if let cachedVersion = cache.object(forKey: "somekey") {
     youImageView.image = cachedVersion.image
}

这篇关于当应用程序进入后台状态时,NSCache 删除其所有数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 23:06