小工具      在线工具  汉语词典  css  js  c++  java

swift3.0 Kingfisher图片库关键源码分析

Swift学习 额外说明

收录于:92天前


1. data 根据url这个key存储在 fetchLoads中

// A single key may have multiple callbacks. Only download once.
    func setup(progressBlock: ImageDownloaderProgressBlock?, with completionHandler: ImageDownloaderCompletionHandler?, for url: URL, options: KingfisherOptionsInfo?, started: ((URLSession, ImageFetchLoad) -> Void)) {

        barrierQueue.sync(flags: .barrier) {
            let loadObjectForURL = fetchLoads[url] ?? ImageFetchLoad()
            let callbackPair = (progressBlock: progressBlock, completionHandler: completionHandler)
            
            loadObjectForURL.contents.append((callbackPair, options ?? KingfisherEmptyOptionsInfo))
            
            //data 根据url这个key存储在 fetchLoads中
            fetchLoads[url] = loadObjectForURL
            
            if let session = session {
                started(session, loadObjectForURL)
            }
        }
    }

2. 获取每次网络传输过来的数据
  func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {

        print("Data......\(data)")
        guard let downloader = downloadHolder else {
            return
        }

        if let url = dataTask.originalRequest?.url, let fetchLoad = downloader.fetchLoad(for: url) {

        1.将获取的数据data放到downloadHolder.fetchLoad (此处的downloader和downloadHolder是同一块内存地址,所以给downloader拼接获取的网络数据,就相当于给downloadHolder拼接数据)中去。
               2.downloadHolder为全局变量,以便于后面获取数据完毕后,可以根据url来取data

           fetchLoad.responseData.append(data) //存储每次获取的数据
       }

3. 网络数据获取完毕,进行图片解码,图片缓存到本地
    //图片数据加载完毕,进入此回调方法
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        
        guard let url = task.originalRequest?.url else {
            retur
        }
        
        guard error == nil else {
            callCompletionHandlerFailure(error: error!, url: url)
            return
        }
        //数据请求完,在此处完成completionHandler 回调
               //在这个函数中,根据url去downloadHolder取image 的data数据,然后解码,存储。
         processImage(for: task, url: url)     
   }

4. 将数据处理成图像的方法

    //数据请求完,在此处完成completionHandler 回调
    //对于每一张根据URL取出来的data,在此做图片的预处理。
    //当选择图片的默认处理方式时,var image = imageCache[processor.identifier]中的
    //processor.identifier = ""处理,具体看identifier的定义说明
    private func processImage(for task: URLSessionTask, url: URL) {

        guard let downloader = downloadHolder else {
            return
        }
        
        // We are on main queue when receiving this.
        downloader.processQueue.async {
            
            guard let fetchLoad = downloader.fetchLoad(for: url) else {
                return
            }
            
            self.cleanFetchLoad(for: url)
            
            let data = fetchLoad.responseData as Data
            
            // Cache the processed images. So we do not need to re-process the image if using the same processor.
            // Key is the identifier of processor.
            var imageCache: [String: Image] = [:]
            for content in fetchLoad.contents {
                
                let options = content.options
                let completionHandler = content.callback.completionHandler
                let callbackQueue = options.callbackDispatchQueue
                
                let processor = options.processor
                
                var image = imageCache[processor.identifier]
                if image == nil {
                    image = processor.process(item: .data(data), options: options)
                    
                    // Add the processed image to cache. 
                    // If `image` is nil, nothing will happen (since the key is not existing before).
                    imageCache[processor.identifier] = image
                }
                
                if let image = image {
                    
                    downloader.delegate?.imageDownloader(downloader, didDownload: image, for: url, with: task.response)
                    
                    if options.backgroundDecode {
                        let decodedImage = image.kf.decoded(scale: options.scaleFactor)
                        callbackQueue.safeAsync { completionHandler?(decodedImage, nil, url, data) }
                    } else {
                        callbackQueue.safeAsync { completionHandler?(image, nil, url, data) }
                    }
                    
                } else {
                    if let res = task.response as? HTTPURLResponse , res.statusCode == 304 {
                        let notModified = NSError(domain: KingfisherErrorDomain, code: KingfisherError.notModified.rawValue, userInfo: nil)
                        
                        //数据请求完,在此处完成completionHandler 回调
                        completionHandler?(nil, notModified, url, nil)
                        continue
                    }
                    
                    let badData = NSError(domain: KingfisherErrorDomain, code: KingfisherError.badData.rawValue, userInfo: nil)
                    callbackQueue.safeAsync { completionHandler?(nil, badData, url, nil) }
                }
            }
        }
    }
}



. . .

相关推荐

额外说明

父类和子类加载顺序-面试被问过一次

总结:先静态后非静态,先父类后子类 -父类静态变量、静态代码块(若有多个按代码先后顺序执行) -子类静态变量、静态代码块(若有多个按代码先后顺序执行) -父类非静态变量、非静态代码块(若有多个按代码先后顺序执行) -父类构造函数 -子类非静态变量、非静态

额外说明

人工智能的三个阶段——连接主义阶段发展至学习阶段

QQ 1274510382 Wechat JNZ_aming 商业联盟 QQ群538250800 技术搞事 QQ群599020441 解决方案 QQ群152889761 加入我们 QQ群649347320 共享学习 QQ群674240731 纪年科技am

额外说明

day34_JdbcTemplate

JdbcTemplate基本使用 01-JdbcTemplate基本使用-概述(了解) JdbcTemplate是spring框架中提供的一个对象,是对原始繁琐的Jdbc API对象的简单封装。spring框架为我们提供了很多的操作模板类。例如:操作关系

额外说明

Linux 配置 multipath 多路径

目录 - 前言 ☀️ 安装 multipath ⭐️ 配置 multipath - 重载 multipath - 前言 通常 Linux 主机挂载存储盘时,每次重启后对应的 /dev/sd* 都会变,而且不好辨识! 这时可以通过 multipath 多路

额外说明

实战篇:Linux 安装 Oracle 11GR2 数据库保姆级教程

前言 相信大家第一次接触Oracle,大都是在windows上安装,比较方便快捷,基本上是一直下一步就可以安装成功。然而企业级的数据库,基本上都是安装在Linux服务器上,安全且高效。 没接触Linux的朋友不用害怕,跟着本篇文章一步步操作,安装Orac

额外说明

【Unity3D应用案例系列】答题系统开发

推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 一、前言 这是本专栏系列的第一篇,答题系统的开发。 这个答题系统,可以从文本文档中提取题目和分数,然后绑定到UI上,在答题的过程中

额外说明

orangepi zero2 全志H616 SSD1306 OLED屏幕测试程序 (已附源码)

orangepi zero2 H616 SSD1306 OLED屏幕测试程序 orangepi zero2 配置wiringpi 库后,突发奇想构建一个测试oled屏幕的程序,放一个蜗牛每次移动一个像素点,实时显示蜗牛的步数,后面要显示其他内容在此代码上

额外说明

【玩转Linux操作】详细讲解Shell的函数,exit,文件重定向,引入外部脚本的操作

-专栏【​​​​​​​玩转Linux操作】 -喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 -音乐分享【Love Story】 -大一同学小吉,欢迎并且感谢大家指出我的问题- 文章目录 -函数 ⭐不获取return值和stdout值 ⭐获取return值

额外说明

统计学基础学习笔记:正态分布

文章目录 一、正态分布概述 二、正态分布概率密度函数 1、概率密度函数 2、参数说明 3、概率密度函数曲线 4、概率密度函数性质 三、正态分布的作用 四、正态分布图形的由来 五、从实际生活中理解正态分布 六、R模拟正态分布 1、画出在-5~5区间,随机变

额外说明

TypeScript 全面介绍

目录 TS(TypeScript) 1. TS的安装和配置 2. 第一个TS程序(举例) 3. 配置自动编译 4. 变量声明 5. 函数 6. 重载 7. class 8. 接口 9. 模块化开发 TS(TypeScript)         旧 JS

ads via 小工具