swift内存缓存NSCache和沙盒磁盘缓存使用教程和demo下载

目录

  • 前言
  • NSCache 和 沙盒的缓存区别
  • NSCache swift中的定义
  • 设置代理
  • 把数据写入NSCache缓存
  • 读取内存缓存NSCache
  • 删除 NSCache数据
  • 代理方法
  • 把数据写入沙盒格式
  • 从沙盒读取数据格式
  • 从网络读取图片例子
  • demo下载地址

前言

以前写过oc的NSCache缓存和沙盒,最近项目也要用到缓存,而且不只是图片还有视频,如果只是图片,用SDWebImage框架自带的缓存机制就行了,但是加上视频,就得自己写了.

NSCache 和 沙盒的缓存区别

NSCache是内存缓存,沙盒是磁盘文件,NSCache因为在内存里保存,所以每次刚启动app的时候是空的什么都没有,如果要想让NSCache读取到内容,必须先往里面写入数据,从沙盒写入或者从网络读取数据写入.沙盒则是磁盘文件,写入以后只要不删除就一直存在,但是磁盘文件读取速度比NSCache内存缓存慢.

NSCache swift中的定义

格式如下:

let cache = NSCache<AnyObject, AnyObject>()
cache

设置代理

需要类遵守协议NSCacheDelegate

cache.delegate = self

把数据写入NSCache缓存

 //把data数据写入内存缓存NSCache
let cache = NSCache<AnyObject, AnyObject>()
cache.setObject(Data数据 as AnyObject, forKey: "key名字" as AnyObject)

读取内存缓存NSCache

let cache = NSCache()
let data = cache.object(forKey: "key名字" as AnyObject)

删除 NSCache数据

cache.removeObject(forKey: "键值" as AnyObject) //删除指定键值的数据
cache.removeAllObjects()  //删除全部

代理方法

即将回收清理cache的时候调用改方法
  func cache(_ cache: NSCache, willEvictObject obj: Any) {
        print("删除缓存",obj)
  }

把数据写入沙盒格式

NSData(data: Data类型数据).write(toFile: 文件路径, atomically: true)

从沙盒读取数据格式

 let imageData = NSData(contentsOfFile: 文件路径) as Data?

从网络读取图片例子

//
//  ViewController.swift
//  NSCacheSwiftDemo
//
//  Created by tdw on 2021/3/19.
//

import UIKit

class ViewController: UIViewController, NSCacheDelegate {
     
    @IBOutlet weak var imageV: UIImageView!
    let urlString = "https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2689708464,460600545&fm=26&gp=0.jpg"
    var cache = NSCache<AnyObject, AnyObject>()
    override func viewDidLoad() {
     
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        cache.delegate = self
    }
    @IBAction func btnLoadFromNet(_ sender: Any) {
     
        //如果缓存没有图片则网络获取
        
        let session = URLSession.shared //URLSession 也有缓存
        let url = NSURL(string: urlString)
        let downloadTask = session.dataTask(with: url! as URL, completionHandler: {
      [unowned self](data, res, error) in
            if error != nil{
     
                print("error=",error)
                return
            }
            guard let data = data else{
     
                print("没取到图片数据")
                return
            }
            //把数据转换为UIImage
            
            //把data数据写入内存缓存NSCache
            self.cache.setObject(data as AnyObject, forKey: urlString as AnyObject)
            print("写入内存缓存NSCache")
            //把data数据写入磁盘沙盒
            //获取沙盒路径
            let disckCache = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).map(\.path).last
            //因为url包含/,但是磁盘缓存文件名不能包含/,所以要去掉/,字符串替换把"/"替换成""
            let fileName = urlString.replacingOccurrences(of:"/", with: "")
            //拼接图片的全路径
            let fullPath = URL(fileURLWithPath: disckCache ?? "").appendingPathComponent(fileName).path
            let isSucess = NSData(data: data).write(toFile: fullPath, atomically: true)
            if isSucess{
     
                print("写入磁盘沙盒缓存")
            }
            DispatchQueue.main.async {
     
                //把UIImage用block传出去
                print("从网络获取图片")
                imageV.image = UIImage(data: data)
            }
        })
        downloadTask.resume()
    }
    
    @IBAction func btnLoadFromMemeryCache(_ sender: Any) {
     
        DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async {
     [unowned self] in
            let data = cache.object(forKey: urlString as AnyObject)
            if (data != nil){
     
                DispatchQueue.main.async {
     
                    imageV.image = UIImage(data: data as! Data)
                }
            }else{
     
                print("内存缓存中无数据")
            }
        }
        
    }
    
    @IBAction func btnDeleteImageV(_ sender: Any) {
     
        imageV.image = nil
    }    
    @IBAction func btnDeleteCache(_ sender: Any) {
     
        //        cache.removeObject(forKey: urlString as AnyObject)
        cache.removeAllObjects()
    }
    //即将回收清理cache的时候调用改方法
    func cache(_ cache: NSCache<AnyObject, AnyObject>, willEvictObject obj: Any) {
     
        print("删除缓存",obj)
    }
    
    //写入磁盘缓存
    @IBAction func btnWriteDiskClick(_ sender: Any) {
     
        //        imageV.image as
    }
    
    //读取磁盘沙盒
    @IBAction func btnReadDiskClick(_ sender: Any) {
     
        //获取沙盒路径
        let disckCache = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).map(\.path).last
        //因为url包含/,但是磁盘缓存文件名不能包含/,所以要去掉/,字符串替换把"/"替换成""
        let fileName = urlString.replacingOccurrences(of:"/", with: "")
        //拼接图片的全路径
        let fullPath = URL(fileURLWithPath: disckCache ?? "").appendingPathComponent(fileName).path
        //检查磁盘缓存
        let imageData = NSData(contentsOfFile: fullPath) as Data?
        if (imageData != nil) {
     
            print("磁盘中有数据")
            //磁盘数据写入UIImage
            imageV.image = UIImage(data: imageData!)
            //磁盘数据写入NSCache
            cache.setObject(imageData as AnyObject, forKey: urlString as AnyObject)
            print("写入内存缓存NSCache")
        }else{
     
            print("没从磁盘中取到数据")
        }
    }
    
}

运行效果
先实验从网上读取数据,然后写入NSCache内存缓存中,再写入磁盘沙盒中,同时把数据写到UIImageView里面,删除图片后,点击从内存加载数据,可以看到能读出来

2.读取网络数据以后,删掉内存缓存NSCache中的数据,再从NSCahce中读取图片,读取失败

3.内存缓存NSCache中无数据的时候,从磁盘缓存中读取数据写入NSCache中,再从NSCache中读取数据,存入UIImageView 成功

4.app刚启动的时候内存中没有数据NSCache读取不到数据,从沙盒缓存中可以读到数据

demo下载地址

你可能感兴趣的:(ios,swift,xcode,ios,swift,NSCache,沙盒,缓存)