如何使用NSCache

123

有人可以举一个使用NSCache缓存字符串的例子吗? 或者有没有好的解释链接?我似乎找不到任何相关的信息。


7
尽管我看到了大量的Cocoa,但我从未听说过NSCache。好问题! - Nektarios
我在这里创建了一个NSCache的可迭代版本,欢迎大家共同贡献:https://github.com/gregkrsak/GKCache - Greg M. Krsak
5个回答

137
您可以像使用NSMutableDictionary一样使用它。区别在于当NSCache检测到过多的内存压力(即缓存太多的值)时,它将释放一些值以腾出空间。
如果您可以在运行时重新创建这些值(通过从互联网下载、进行计算等),那么NSCache可能适合您的需求。如果数据无法重新创建(例如用户输入、时间敏感等),则不应将其存储在NSCache中,因为它会被销毁。
示例(不考虑线程安全):
// Your cache should have a lifetime beyond the method or handful of methods
// that use it. For example, you could make it a field of your application
// delegate, or of your view controller, or something like that. Up to you.
NSCache *myCache = ...;
NSAssert(myCache != nil, @"cache object is missing");

// Try to get the existing object out of the cache, if it's there.
Widget *myWidget = [myCache objectForKey: @"Important Widget"];
if (!myWidget) {
    // It's not in the cache yet, or has been removed. We have to
    // create it. Presumably, creation is an expensive operation,
    // which is why we cache the results. If creation is cheap, we
    // probably don't need to bother caching it. That's a design
    // decision you'll have to make yourself.
    myWidget = [[[Widget alloc] initExpensively] autorelease];

    // Put it in the cache. It will stay there as long as the OS
    // has room for it. It may be removed at any time, however,
    // at which point we'll have to create it again on next use.
    [myCache setObject: myWidget forKey: @"Important Widget"];
}

// myWidget should exist now either way. Use it here.
if (myWidget) {
    [myWidget runOrWhatever];
}

1
如何实例化NSCache对象?每次运行应用程序时,我似乎都会丢失所有缓存的信息。我使用; [[NSCache alloc] init] - Thizzer
18
它不是永久存储在磁盘上的缓存。它仅保存在内存中,因此每次您的应用停止运行时都会被清除。 - Jonathan Grynspan
当应用程序进入后台后,这个缓存是否会被维护?(即在applicationDidEnterBackground之后) - barfoon
如果应用程序没有终止且NSCache对象没有被释放,那么它将会一直存在于内存中。但是,它的内容仍然可能会受到削减。 - Jonathan Grynspan
3
不。一个断言(assertion)会声明某件事情是真实的,也就是说声明语句本身应该是正确的。我们在声明对象的赋值和/或创建成功。 - Jonathan Grynspan
显示剩余4条评论

19
@implementation ViewController
{    
    NSCache *imagesCache;    
}


- (void)viewDidLoad
{    
    imagesCache = [[NSCache alloc] init];
}


// How to save and retrieve NSData into NSCache
NSData *imageData = [imagesCache objectForKey:@"KEY"];
[imagesCache setObject:imageData forKey:@"KEY"];

3
可以的。保存:[imagesDictionary setObject:imageData forKey:@"KEY"]; 获取:NSData *imageData = [imagesCache objectForKey:@"KEY"]; (翻译说明:这是一段代码,原文已经很简单易懂,因此我只对代码中的关键字进行了翻译并保留了原始结构。) - Gabriel.Massana
2
将数据保存到缓存:[imagesCache setObject:imageData forKey:@"KEY"]; - kas-kad
1
我刚刚编辑了帖子,将imagesDictionary更改为imagesCache。谢谢。 - Gabriel.Massana
一个等价的 Swift 示例? - Jasper

10

使用Swift中的NSCache进行字符串缓存的示例代码:

var cache = NSCache()
cache.setObject("String for key 1", forKey: "Key1")
var result = cache.objectForKey("Key1") as String
println(result) // Prints "String for key 1"
为创建一个应用程序范围内的单例NSCache实例,可以通过扩展NSCache并添加一个sharedInstance属性来轻松实现。只需将以下代码放入名为NSCache+Singleton.swift的文件中即可:
```swift extension NSCache { static let sharedInstance = NSCache() } ```
import Foundation

extension NSCache {
    class var sharedInstance : NSCache {
        struct Static {
            static let instance : NSCache = NSCache()
        }
        return Static.instance
    }
}

接下来,您可以在应用程序的任何地方使用缓存:

NSCache.sharedInstance.setObject("String for key 2", forKey: "Key2")
var result2 = NSCache.sharedInstance.objectForKey("Key2") as String
println(result2) // Prints "String for key 2"

3
你知道如何在Swift 3中实现这个吗? - Andrew
3
这应该能起作用: static let shared = NSCache() private override init() { super.init() } }``` (说明:这是一段 Swift 代码,定义了一个名为 `Cache` 的类和一个名为 `shared` 的静态属性,用于存储缓存数据。) - AmitaiB

6

示例项目 将示例项目中的CacheController.h和.m文件添加到您的项目中。在需要缓存数据的类中,放置以下代码。

[[CacheController storeInstance] setCache:@"object" forKey:@"objectforkey" ];

使用此功能,您可以设置任何对象

[[CacheController storeInstance] getCacheForKey:@"objectforkey" ];

检索数据

重要提示:NSCache类采用各种自动删除策略。如果您想永久缓存数据或者想在特定时间内删除缓存的数据,请查看此答案


1

缓存对象不应该实现NSDiscardableContent协议吗?

从NSCache类参考中可以看到: 在NSCache对象中存储的常见数据类型是实现NSDiscardableContent协议的对象。将这种类型的对象存储在缓存中有益处,因为当它们不再需要时,其内容可以被丢弃,从而节省内存。默认情况下,如果缓存中的NSDiscardableContent对象的内容被丢弃,则会自动从缓存中删除这些对象,尽管可以更改此自动删除策略。如果将NSDiscardableContent对象放入缓存中,则在其被移除时,缓存会调用discardContentIfPossible方法。


1
您可以实现NSDiscardableContent协议,但这并非必需。似乎当没有更多引用时,NSDiscardableContent总是从NSCache中移除的。除NSDiscardableContent对象之外的其他对象存储在NSCache中,直到出现“内存紧张”的情况,NSCache将被清除。 - Thizzer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接