reference doc NSCache
SDKs
iOS 4.0+
macOS 10.6+
tvOS 9.0+
watchOS 2.0+
class
NSCache
A mutable collection you use to temporarily store transient key-value pairs that are subject to eviction when resources are low.
是一个可变集合,可用于临时存储瞬态键值对,当接收到系统资源快要耗尽是会执行删减已存储的瞬态键值对的行为。
Overview
Cache objects differ from other mutable collections in a few ways:
- The NSCache class incorporates various auto-eviction policies, which ensure that a cache doesn’t use too much of the system’s memory. If memory is needed by other applications, these policies remove some items from the cache, minimizing its memory footprint.
- You can add, remove, and query items in the cache from different threads without having to lock the cache yourself.
- Unlike an NSMutableDictionary object, a cache does not copy the key objects that are put into it.
以下是 Cache 与 其他可变集合的区别:
- NSCache 类结合了各种自动回收策略,Cache 实例不会对系统内存造成过多的压力。如果系统的其他应用也需要内存分配时,NSCache 就会按照给定的回收策略移除存放的项目,尽量减少它的内存占用。
- NSCache是线程安全的,你可以在不同的线程内对 NSCache 实例进行增、删、查等操作。
- 与NSMutableDictionary对象不同的是,NSCache实例是不会对存放进来的键值对执行 copy 操作。
You typically use NSCache objects to temporarily store objects with transient data that are expensive to create. Reusing these objects can provide performance benefits, because their values do not have to be recalculated. However, the objects are not critical to the application and can be discarded if memory is tight. If discarded, their values will have to be recomputed again when needed.
每次都通过创建新的 NSCache 对象来临时存储瞬态数据的性能消耗是比较高的。而重用已创建的NSCache 对象则有益于性能的提升,因为可以不再对已存储的值所要占用的内存进行重新计算。需要注意的是,如果这些存放的值被移除时对应用不能有任何影响,因为当内存发生警告这些对象就会被移除,移除后的值如果再被调用的话则会进行重新计算。
question:当内存警告发生时,是 NSCache 对象被移除?还是里面已经存放的值被移除?假设移除了值,那么还能重新获取该值吗?
Objects that have subcomponents that can be discarded when not being used can adopt the NSDiscardableContent protocol to improve cache eviction behavior. By default, NSDiscardableContent objects in a cache are automatically removed if their content is discarded, although this automatic removal policy can be changed. If an NSDiscardableContent object is put into the cache, the cache calls discardContentIfPossible on it upon its removal.
如果Cache存放的一些具有 subcomponents 且可被废弃的对象时,当该对象未被使用的话,可以让对象通过遵守NSDiscardableContent协议来提升 Cache 的释放行为性能。默认情况下,遵守NSDiscardableContent协议的对象在它的 Content 被废弃后会自动地被 Cache 实例移除,即使改变 Cache 的自动移除策略,该行为同样会执行。当Cache 缓存了遵守NSDiscardableContent协议的对象时,Cache 实例会调用该对象实现的NSDiscardableContent协议的方法discardContentIfPossible,当该对象被移除时
NSCache.h
#import <Foundation/NSObject.h>
@class NSString;
@protocol NSCacheDelegate;
NS_ASSUME_NONNULL_BEGIN
NS_CLASS_AVAILABLE(10_6, 4_0)
@interface NSCache <KeyType, ObjectType> : NSObject {
@private
id _delegate;
void *_private[5];
void *_reserved;
}
@property (copy) NSString *name;
@property (nullable, assign) id<NSCacheDelegate> delegate;
- (nullable ObjectType)objectForKey:(KeyType)key;
- (void)setObject:(ObjectType)obj forKey:(KeyType)key; // 0 cost
- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;
- (void)removeObjectForKey:(KeyType)key;
- (void)removeAllObjects;
@property NSUInteger totalCostLimit; // limits are imprecise/not strict
@property NSUInteger countLimit; // limits are imprecise/not strict
@property BOOL evictsObjectsWithDiscardedContent;
@end
@protocol NSCacheDelegate <NSObject>
@optional
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;
@end
NS_ASSUME_NONNULL_END
Topics
设置 Cache 实例的名字
name
默认值是空字符串@“”;
限制缓存大小
countLimit
最大缓存个数;
默认值为0,当值为0时候即表示没有个数限制;
这不是一个严格的限制值,如果缓存超过countLimit所设定的值,已存在缓存中的某个对象,默认的情况下会被马上移除,但实际上可能稍后移除,也有可能不移除。这些都取决于 Cache 内部实现。
totalCostLimit
在执行清除缓存动作前,缓存支持的最大缓存成本值。
默认值为0,为0则表示不设限制。
如果你添加到缓存内的对象,刚好超出了你指定的totalCostLimit值(缓存总成本),那么缓存会自动地执行释放已缓存对象操作,直到可以缓存下你添加的对象同时整个缓存成本低于你指定的totalCostLimit值。需要注意的是,释放已缓存对象的顺序是不确定的。
totalCostLimit同样不是一个严格的限制值,如果缓存超过totalCostLimit所设定的值,已存在缓存中的某个对象,默认的情况下会被马上移除,但实际上可能稍后移除,也有可能不移除。这些都取决于 Cache 内部实现。
Ref
iOS系统中缓存的使用
这个基本上是参考 52个高效方法的内容描述