iOS中一个被忽视的类NSCache

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

在日常开发中,对相同内容做重复的请求没有什么意义而且还会影响应用程序的性能,因此经常会需要存储一些临时内容,以便重用,例如从网络加载的图片、文件等。

在 Swift 中系统为我们提供了 NSCache,可以在内存中存储临时数据。它是一个可变集合,以键值对的形式存储,而且 NSCache 自带清除功能,这些键值对在资源不足时会被清除。

很多第三方库的底层其实都在用 NSCache 做存储,比如常用的 Kingfisher,因为它非常的简单易用,又安全。

使用方法

1. 初始化

NSCacheKeyValue 都是范型,因此需要在声明的时候指定其类型,比如我这里存储的 keyNSStringvalueUIImage:

swift 复制代码
let cache = NSCache<NSString, UIImage>()

KeyValue 都必须是 AnyObject,因此值类型是不能用 NSCache 存储的

2. 添加对象到缓存

less 复制代码
cache.setObject(UIImage(named: "apple.png")!, forKey: "apple")

3. 从缓存中获取对象

csharp 复制代码
let image = cache.object(forKey: "apple")

4. 设置缓存最大对象数

ini 复制代码
cache.countLimit = 100

如果设置为 0,则不限制存储数量,默认值为 0

这个参数并不是一个严格的限制,如果缓存超过了设置的限制,缓存中的对象可能会立即释放,也可能稍后释放,这取决于底层的实现细节。

5. 设置最大存储容量

ini 复制代码
cache.totalCostLimit = 1024 * 1024 * 100 

以上代码设置了 100MB 的存储容量,也就是说,如果超过了这个值,就会开始清除缓存的对象。

6. 移除某个缓存

less 复制代码
cache.removeObject(forKey: "apple")

7. 移除所有缓存

scss 复制代码
cache.removeAllObjects()

8. 即将被移除的代理监听

NSCache 还提供了一个代理,当对象即将从缓存中清除或删除时调用,首先绑定代理:

ini 复制代码
cache.delegate = self

然后实现代理方法:

swift 复制代码
extension ViewController: NSCacheDelegate {
    func cache(_ cache: NSCache<AnyObject, AnyObject>, willEvictObject obj: Any) {
        // obj 缓存将要被移除时执行
    }
}

NSCache 的优势

  1. 自动内存管理 :当系统内存不足时,NSCache会自动删除部分缓存对象。

  2. 线程安全:可以在多个线程中同时使用,无需加锁。

  3. 键-值对存储 :提供了类似 NSDictionary 的接口,但比 NSDictionary 更适合用作缓存。

NSCache 的缺陷

  1. 不可控性 :这是最大的缺点,苹果文档中也有描述,即使你设置了 countLimittotalCostLimit,也不能保证何时清除缓存或清除哪些对象。

  2. 缺乏持久性:这些数据不是存储在磁盘上的,当应用程序重启后,缓存的数据将被清空。

  3. 无法设置过期时间 :与其他一些缓存机制相比,NSCache 无法为单个对象设置过期时间,Kingfisher 中的过期时间也是作者自己实现的。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
getapi4 小时前
1 在 macOS 电脑上更新 Flutter iOS 应用到 App Store
flutter·macos·ios
可乐鸡翅yeah_4 小时前
App WebView 加载 M3U8 流媒体踩坑,安卓 iOS 混合开发播放异常定位
android·ios·harmonyos·m3u8·m3u8在线播放
东坡肘子4 小时前
当 Mac mini 的价格不再 mini -- 肘子的 Swift 周报 #152
人工智能·swiftui·swift
代码的小搬运工18 小时前
KVO学习
学习·ios·cocoa
方白羽18 小时前
为什么 Android 非要用 Intent 传值?
android·ios·harmonyos
dora19 小时前
iOS开发新手的第一行代码
ios
用户38034165882971 天前
视频编辑器的滤镜图内核:Node/Pin 模型怎么设计,撤销重做怎么才不崩
ios
CocoaKier2 天前
苹果续费成功,几天后付费协议突然失效,导致线上苹果支付全部失败
ios·apple
刘广睿2 天前
素材库智能集合怎么设计?把多维筛选存成动态收藏的功能复盘
客户端·架构设计·产品设计·素材管理
深念Y2 天前
PVE 安装黑苹果并直通 Quadro P400
macos·ios·黑苹果·驱动·苹果·英伟达·p400