为避免撕逼,提前声明:本文纯属翻译,仅仅是为了学习,加上水平有限,见谅!
NSCache
你用来短暂存储临时键值对的可变集合,且在资源不足时可以把它回收掉。
概述
缓存对象同其他可变集合的几个不同的地方:
NSCache类包含多种自动回收策略,这确保缓存不会耗费太多系统内存。如果其他应用需要内存,这些策略会从缓存中移除一些数据,以减少它对内存的占用。- 你可以用不同的线程在不需要对缓存加锁的情况下向缓存中添加、移除和查询数据。
- 不像NSMutableDictionary对象,缓存不会复制放入其中的键对象。
通常的,你使用NSCache对象去短暂的存储需要花费高成本创建的临时对象。重用这些对象可以带来性能上的好处,因为他们的值不需要重新计算。然而,对应用来不是很关键的对象会在内存紧张的时候废弃掉。如果废弃掉,在再需要这些值的时候就需要重新计算。
具有子部分的对象不再使用的会被回收掉,这可以采用NSDiscardableContent去改善缓存回收行为。默认情况下,他们的内容在缓存中的NSDiscardableContent对象在他们的内容被丢弃后可以自动的移除掉,尽管这个自动移除策略可以改变。如果一个NSDiscardableContent对象存入到了缓存中,缓存在移除它的时候会对它调用discardContentIfPossible。
属性
name
实例属性
缓存名称
声明
@property(copy) NSString *name;
讨论
默认值是一个空字符串("")
countLimit
缓存可以保存对象的最大值
声明
@property NSUInteger countLimit;
讨论
如果等于0,那么就没有数量限制。默认值是0.
这不是严格的限制,如果缓存超出限制,缓存中的对象可以立即回收或者永远不回收,这取决于缓存的详细实现。
totalCostLimit
在开始回收对象之前的缓存可以容纳的最大值
声明
@property NSUInteger totalCostLimit;
讨论
如果为0,则没有最大值限制。默认值是0.
当你往缓存中添加对象的时候,可能会对对象传递一个指明的成本,例如对象的字节大小。如果向缓存中添加这个对象导致缓存的总成本超过totalCostLimit,缓存可能会自动回收对象知道它的总成本低于totalCostLimit。缓存回收对象的顺序是无法确定的。
这个限制并不严格,如果缓存超过限制,缓存中的对象可能会被立即回收、也可能是晚些时候或者永远不会,这都取决于缓存的具体实现。
evictsObjectsWithDiscardedContent
缓存是否会自动回收内容废弃的对象
声明
@property BOOL evictsObjectsWithDiscardedContent;
讨论
如果是YES的话,缓存会自动回收内容已废弃的对象。如果是NO,则不会。默认值是YES。
delegate
缓存的委托
声明
@property (assign) id<NSCacheDelegate> delegate;
讨论
这个委托必须遵守NSCacheDelegate协议。
协议
NSDiscardableContent
NSCacheDelegate
方法
- objectForKey:
返回同给定的键值相关联的值。
声明
- (ObjectType)objectForKey:(KeyType)key;
参数
key 标识一个值的对象。
返回值
与键相关的值,或者如果与键相关的值不存在的话,则返回nil。
setObject:forKey:
为缓存中特定的键设置值。
声明
- (void)setObject:(ObjectType)obj forKey:(KeyType)key;
参数
obj 存储在缓存中的对象
key 同值相关的键。
讨论
不像NSMutableDictionary对象那样,缓存不会拷贝放在其中的键对象。
setObject:forKey:cost:
为缓存中特定的键设置值,同时为键值对设置特定的成本(占用空间)。
声明
- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;
参数
obj 存储在缓存中的对象
key 同值关联的键。
num 同键值对相关的成本(占用空间)。
讨论
一个用来计算包含在缓存中所有对象的占用空间总值的cost值。当内存有限或当总的成本(占用空间)超过允许的总成本(占用空间)时,缓存可以启动一个回收过程把其中的一些元素移除。然而,这个回收过程不按照指定的顺序进行。因此,如果你试图篡改成本(占用空间)值去达到特定的行为,这样可能会对你的程序没有益处。通常,明显的成本是字节码的值。如果这些信息不是现成的,你不应该费力的去计算它,因为这样会增加使用缓存的成本。如果你没有任何有用的信息,你可以想成本中传递0或者简单地使用setObject:forKey:方法,这个方法不需要传递成本值。
不像NSMutableDictionary对象,缓存不会拷贝放进去的键对象。
removeObjectForKey:
移除缓存中的特定键对应的值。
声明
- (void)removeObjectForKey:(KeyType)key;
参数
key 标识将要移除值的键。
removeAllObjects
清空缓存
声明
- (void)removeAllObjects;
NSDiscardableContent
如果你实现了这个协议,在类对象中的属性没有被使用的时候会将其空间废弃掉,从而让应用的内存占用更加小。
概述
NSDiscardableContent对象的生命周期取决于“计数”变量。NSDiscardableContent对象是一个可清除的内存块,用于跟踪它是否正被其他对象使用。当这个内存正被读取或还被使用时,它的计数变量将被增加或者设置为1。当未被使用或废弃时,计数变量会被设置为0。
当计数器是0时,如果当时内存紧张内存块会被废弃。为了要废弃内容,在对象中调用discardContentIfPossible方法,如果计数变量为0时将会释放相关的内存。
默认情况下,NSDiscardableContent对象初始化的时候把计数变量设置为1,用以保证它们不会立即被内存管理系统回收。由此,你必须对计数变量的状态进行跟踪。调用beginContentAccess方法会对计数器加1,这样可以保证对象不会被回收。当你不再需要这个对象时,调用endContentAccess方法会递减计数器。
Foundation框架包含NSPurgeableData类,这个类提供这个协议的默认实现。
主题
方法
beginContntAccess
返回一个布尔值,它用来指示可废弃的内容是否可用、是否可以成功访问。
Required
声明
- (BOOL)beginContentAccess;
返回值
如果可废弃的内容仍然可用且可以成功访问,则YES;否则返回NO
讨论
如果需要且打算使用对象的内存,可以调用此方法。这个方法会增加计数器的值,以此来保护对象的内存不会被回收。实现了可以决定这个方法重新创建已经废弃的内容,并在创建成功后返回YES。如果在未调用beginContentAccess方法的时候使用NSDiscardableContent对象,这个协议的实现者应该会出现异常。
endContentAccess
如果可回收的内容不在被访问,则可以调用此方法
Required
声明
- (void)endContentAccess;
讨论
这个方法会递减这个对象的计数变量,这通常将会把计数器的值减到0,如果需要的话,它可以回收对象的可回收内容。
discardContentIfPossible
如果获取到的计数器值为0,调用这个方法去回收接收者的内容。
声明
- (void)discardContentIfPossible;
讨论
如果获取到的计数器的值为0,这个方法会回收对象的内容。否则,什么都不做。
isContentDiscarded
返回一个布尔值,表明内容是否已被回收。
Required
声明
- (BOOL)isContentDiscarded;
返回值
如果内容已被回收,怎返回YES;否则返回NO。
NSCacheDelegate
当打算去回收对象或者把对象从缓存中移除的时候,NSCache对象的委托实现这个协议去执行特定的动作。
方法
cache:willEvictObject:
当打算回收对象或者把对象从缓存中回收的时候,可以调用这个方法。
声明
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;
参数
cache 与感兴趣的对象相关联的缓存。
obj 缓存中感兴趣的对象。
讨论
不可能在这个委托方法的实现中修改缓存。