一. 缓存原理

图片缓存原理原理是,如内存没图片,去磁盘找,若磁盘也没有,则根据url去下载,然后缓存到内存和磁盘中,简单易用

缓存的目录结构如下图:

 //存储图片的文件夹
 var ljFilePath:String =NSHomeDirectory()  "/Documents/" "LJImageCache/"

二. 图片名称处理

为了确保缓存下来的图片的唯一性,所以此处采用图片的url md5=唯一标识符,来存储图片,如上图图片的名称。

创建一个Sting MD5.swift字符串分类文件(同时此处需要创建一个bridge.h桥接文件,引入这个头文件

#import <CommonCrypto/CommonDigest.h>,md5加密方法需要使用的文件)

1.bridge.h桥接文件如下:

#ifndef bridge_h 
#define bridge_h 
 
#import <CommonCrypto/CommonDigest.h> 
 
#endif /* bridge_h */ 

2. Sting MD5.swift文件如下

import Foundation 
 
extension String { 
  var md5 : String{ 
    let str = self.cString(using: String.Encoding.utf8) 
    let strLen = CC_LONG(self.lengthOfBytes(using: String.Encoding.utf8)) 
    let digestLen = Int(CC_MD5_DIGEST_LENGTH) 
    let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen) 
     
    CC_MD5(str!, strLen, result) 
     
    let hash = NSMutableString() 
    for i in 0 ..< digestLen { 
      hash.appendFormat("x", result[i]) 
    } 
    result.deinitialize() 
     
    return String(format: hash as String) 
  } 
} 

三.图片缓存和读取

1. 图片缓存

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) 
  { 
    if ljcallBackClosure != nil ,let data = self.responseData{ 
      weak var weakSelf : LJOpreationManager? = self 
      DispatchQueue.main.async 
      { 
        print("URLSessionDataDelegate----数据下载完毕") 
         
        LJCacheDataManage.shared.setMemoryCache((task.currentRequest?.url?.absoluteString)!,data as Data) 
         
        //图片缓存,根据唯一的url来作为存储数据的名称 
        let a = LJFileManager.shared.writeFile((task.currentRequest?.url?.absoluteString)!,data as NSData) 
         
        print("-----写入文件成功\(a)") 
         
        //将接收的数据结果回调到前台,用于进度展示 
        weakSelf?.ljcallBackClosure!(data as Data ,nil) 
      } 
    } 
  } 

2.图片读取

public func retrieveImage(_ ljurl: String, _ ljcallback: @escaping OpreationClosure){ 
     
    if ljurl != "" { 
       
      if LJFileManager.shared.readFileFromCache(ljurl) != nil { 
        //将接收的数据结果回调到前台,用于进度展示 
        print("获取的是Disk缓存数据哦完毕") 
        ljcallback(LJFileManager.shared.readFileFromCache(ljurl) as! Data,nil) 
      } 
      //首先取缓存数据,没取到的话,直接下载 
     else if LJCacheDataManage.shared.getMemoryCache(ljurl) != nil { 
        //将接收的数据结果回调到前台,用于进度展示 
        print("获取的是Memory缓存数据哦完毕") 
        ljcallback(LJCacheDataManage.shared.getMemoryCache(ljurl) ,nil) 
      } 
      else 
      { 
       _ = self.requestWebByUrl(ljurl, ljcallback) 
      } 
    } 
  } 

3. 读写磁盘文件

(1)存储的时候给url进行md5加密得到fileName.md5文件名称,然后存储,如上面的截图

(2)读取文件时,给url进行md5加密得到path.md5的,然后获取文件数据

/* 写文件 
  fileName: 文件名称 
  data: 数据data 
*/ 
func writeFile(_ fileName:String , _ data:NSData) -> Bool{ 
   
  //let filePath:String = NSHomeDirectory()   "/Documents/"   fileName.md5 
  //return data.write(toFile: filePath, atomically: true) 
  guard self.isExistFileDir(ljFilePath) else{ 
    return false 
  } 
   
  guard let filePath : String = ljFilePath   fileName.md5 else{ 
    return false 
  } 
  return data.write(toFile: filePath, atomically: true) 
} 
 
//读取文件 -(根据路径) 
func readFileFromCache(_ path:String) -> NSData?{ 
   
  if self.isExistFileDir(ljFilePath) 
  { 
    let ljpatch = ljFilePath   path.md5 
    var result:NSData? 
    do{ 
      result = try NSData(contentsOfFile: ljpatch, options: Data.ReadingOptions.uncached) 
    }catch{ 
      return nil 
    } 
    return result 
  } 
  return nil 
} 

4.读写内存文件

import Foundation 
 
class LJCacheDataManage: NSObject{ 
   
  //单例 
  public static let shared = LJCacheDataManage() 
   
  // public var diskCache = 
   
  //缓存的数据 
  public var memoryCache = Dictionary<String, Data>() 
   
  //返回缓存的数据 
  func getMemoryCache(_ urlStr : String) -> Data? { 
     
    print("返回缓存的数据------\(memoryCache[urlStr] ?? nil)") 
    return (memoryCache[urlStr] ?? nil) 
  } 
   
  //设置缓存值 
  func setMemoryCache(_ urlStr : String, _ data : Data){ 
    if urlStr != "", data != nil { 
      memoryCache[urlStr] = data 
    } 
  } 
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Devmax。

swift3.0网络图片缓存原理简析的更多相关文章

  1. Swift 进阶 —— map 和 flatMap的使用

    这篇文章主要介绍了Swift map和flatMap的相关资料,帮助大家更好的理解和使用Swift,感兴趣的朋友可以了解下

  2. Swift和Objective-C 混编注意事项

    这篇文章主要介绍了Swift和Objective-C 混编注意事项的相关资料,需要的朋友可以参考下

  3. Swift 2.1 为 UIView 添加点击事件和点击效果

    本文主要介绍 Swift UIView,这里给大家提供代码示例作为参考为UIView 添加点击事件和点击效果,希望能帮助IOS开发的同学

  4. iOS swift 总结NavigationController出现问题及解决方法

    这篇文章主要介绍了iOS swift 总结NavigationController出现问题及解决方法的相关资料,需要的朋友可以参考下

  5. iOS中关于Swift UICollectionView横向分页的问题

    这篇文章通过图文并茂的形式给大家介绍UICollectionView横向分页的问题,非常不错,具有参考借鉴价值,需要的的朋友参考下吧

  6. IOS swift3.0 下闭包语法整理

    这篇文章主要介绍了IOS swift3.0 下闭包语法整理的相关资料,需要的朋友可以参考下

  7. iOS 中Swift仿微信添加提示小红点功能(无数字)

    这篇文章主要介绍了iOS 中Swift仿微信添加提示小红点功能(无数字),非常不错,具有参考借鉴价值,需要的朋友可以参考下

  8. IOS  Swift3 四种单例模式详解及实例

    这篇文章主要介绍了IOS Swift3 四种单例模式详解及实例的相关资料,这里对四种单例模式进行了实例介绍 ,需要的朋友可以参考下

  9. 浅谈SwiftUI 里面$0是什么意思如何用

    这篇文章主要介绍了浅谈SwiftUI 里面$0是什么意思如何用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  10. EarthLiveSharp中cloudinary的CDN图片缓存自动清理python脚本

    这篇文章主要介绍了EarthLiveSharp暂时没有清理cloudinary的CDN图片缓存的功能,于是我用python写了一个,并尝试用gist管理,需要的朋友可以参考下

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部