1.NSCache
一般运用NSCache目标暂时存储具有创立本钱高昂的瞬时数据的目标。重用这些目标能够提高性能,由于它们的值不必从头计算。然而,这些目标对应用程序来说并不重要,假如内存不足,能够将其丢掉。假如丢掉,则在需要时有必要从头计算它们的值。
NSCache是一个可变键值对调集,运用办法和NSMutableDictionary基本是相同。不过相对于NSMutableDictionary,NSCache有以下几个差异:
1.NSCache是线程安全的,NSMutableDictionary线程不安全。
2.当内存不足时,NSCache可能会主动删去键值对以开释内存,所以从缓存中取数据的时分总要判别是否为空。删去战略未知。
3.NSCache能够指定缓存限额,当缓存超出限额时主动开释内存。
4.NSCache的键仅仅对目标的强引证,目标不需要完成NSCopying协议。NSMutableDictionary的键会copy目标,目标有必要完成NSCopying协议。
// UIView目标没有完成NSCopying协议
UIView *view = [[UIView alloc] init];
// 没有问题
[self.cache setObject:view forKey:view];
// 会溃散,由于key没有完成NSCopying协议
[self.dic setObject:view forKey:view];
运用办法
1.设置缓存限额
// 缓存数量
@property NSUInteger countLimit;
// 缓存本钱
@property NSUInteger totalCostLimit;
2.监听元素移除
@property (nullable, assign) id<NSCacheDelegate> delegate;
// 在移除元素之前,会回调下面的办法,回来要移除的元素。
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;
代码演示:
#import "ViewController.h"
@interface ViewController () <NSCacheDelegate>
// 定义缓存池
@property (nonatomic, strong) NSCache *cache;
@end
@implementation ViewController
- (NSCache *)cache {
if (_cache == nil) {
_cache = [[NSCache alloc] init];
// 缓存中一共能够存储多少条
_cache.countLimit = 5;
// 缓存的数据总量为多少,5k
_cache.totalCostLimit = 1024 * 5;
// 设置署理
_cache.delegate = self;
}
return _cache;
}
- (void)viewDidLoad {
[super viewDidLoad];
// 增加缓存数据
for (int i = 0; i < 10; i++) {
[self.cache setObject:[NSString stringWithFormat:@"hello %d",i] forKey:[NSString stringWithFormat:@"h%d",i]];
NSLog(@"增加 %@",[NSString stringWithFormat:@"hello %d",i]);
}
// 输出缓存中的数据
for (int i = 0; i < 10; i++) {
NSLog(@"%@",[self.cache objectForKey:[NSString stringWithFormat:@"h%d",i]]);
}
}
// 当缓存被移除的时分执行
- (void)cache:(NSCache *)cache willEvictObject:(id)obj{
NSLog(@"缓存移除 %@",obj);
}
控制台输出成果为:
2.NSMapTable
NSMapTable是一个可变键值对调集,运用办法和NSMutableDictionary基本是相同。不过相对于NSMutableDictionary,NSMapTable有以下几个差异:
1.能够设置是否强引证键目标,NSMutableDictionary只能强引证键目标。假如键目标开释了,NSMapTable会主动移除键值对。
2.能够设置是否强引证值目标,NSMutableDictionary只能强引证值目标。假如值目标开释了,NSMapTable会主动移除键值对。
、、、
// 键值都是强引证,相当于NSMutableDictionary
- (NSMapTable<KeyType, ObjectType> *)strongToStrongObjectsMapTable;
// 键目标是弱引证,值目标是强引证。当键目标开释的时分,NSMapTable就会移除这对键值对。 - (NSMapTable<KeyType, ObjectType> *)weakToStrongObjectsMapTable;
// 键目标是强引证,值目标是弱引证。当值目标开释的时分,NSMapTable就会移除这对键值对。 - (NSMapTable<KeyType, ObjectType> *)strongToWeakObjectsMapTable;
- // 键值都是弱引证。当键目标或者值目标只要有一个开释,NSMapTable就会移除这对键值对。
- (NSMapTable<KeyType, ObjectType> *)weakToWeakObjectsMapTable;
、、、
代码演示
- (void)viewDidLoad {
NSMutableString *key = [[NSMutableString alloc] initWithString:@"key"];
NSMutableString *value = [[NSMutableString alloc] initWithString:@"value"];
NSMapTable *mapTable = [NSMapTable weakToStrongObjectsMapTable];
[mapTable setObject:value forKey:key];
NSLog(@"开释之前---%@", mapTable);
key = nil;
NSLog(@"开释之后---%@", mapTable);
}
控制台输出成果为:
开释之前---NSMapTable {
[5] key -> value
}
开释之后---NSMapTable {
}
3.NSHashTable
NSHashTable是一个可变调集,运用办法和NSMutableSet基本是相同。不过相对于NSMutableArray,NSMutableArray有以下几个差异:
1.能够设置调集内元素的内存管理办法,例如强引证,弱引证。当元素弱引证并开释的时分,NSHashTable会主动移除这个元素。
代码演示
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableString *object = [[NSMutableString alloc] initWithString:@"object"];
// 设置对调集内的元素为弱引证
NSHashTable *hashTable = [NSHashTable weakObjectsHashTable];
[hashTable addObject:object];
NSLog(@"开释之前---%@", hashTable);
object = nil;
NSLog(@"开释之后---%@", hashTable);
}
控制台输出成果为:
开释之前---NSHashTable {
[1] object
}
开释之后---NSHashTable {
}