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