SDWebImage源码分析(-)

   本篇文章主要记录自己阅读SDWebImage时,对SDWebImage的理解,如果有不正确的地方,欢迎指正
   SDWebImageView获取图片的主要思路是:开始从缓存NSCache里面取,取到了就返回;如果没有取到就从本地磁盘上取,取到了就设置缓存然后返回;如果没有取到就从url路径里面下载。

   本文从文件"SDWebImageView+WebCashe.h"说起,这个文件主要是设置图片UIImageView的分类,有很多sd_setImageWithUrl的实例方法,最终主要是调用下面这个方法:


 
这个方法里面主要做了如下几件事情:
     a):如果当前有正在下载的任务,就取消下载的任务;[self sd_cancelCurrentImageLoad];
     b):使用运行时将当前的self对象和url关联起来,objc_setAssociatedObject(........);
   c):如果不是延时加载placehoder,就直接在主线程中将placeHoder复制给当前的self,即调用者UIImageView对象,self.image=placehoder;
     d):如果图片的url不为空,就做下载的操作,后面详细介绍
     e):如果url为空,就在主线程里面抛出异常,以及移除UIActivityIndicatorView视图,这个操作个人不是很理解.

首先看a步骤,最终调用如下的方法,key的值为"UIImageViewImageLoad",表示图片正在加载


    第一句话[self operationDictionary]主要做的事情是通过运行时从self里面由键&loadOperationKey取到可变字典对象,取到了就直接返回,没有取到就生成一个,并且用运行时和当前的self关联,即动态添加了一个属性,然后返回这个可变的字典。
    后面接着通过key来获取字典里面的值,即下载的操作,如果有值,就去取消下载的操作,看这个方法[operaion cancel];

  如果当前的线程不为空,就停止RunLoop,这个地方不是很理解,后面程序在下载图片的时候,会开启RunLoop,然后取消connection,[self reset]主要是将下载时候的一些参数设置为空,因为这个步骤就是取消当前正在下载的任务,这一块基本结束


再看d步骤,主要就是调用SDWebImageManager的下载方法。

方法前面几行代码主要是url参数的校验,以及是加载失败的url并且加载失败的url不重新处理的话,就直接返回异常。后面就将当前的操作operation存入正在执行的操作的字典runningOperations。

    接着就是从缓存/本地获取图片,使用的是如下方法


[self imageFromMemoryCacheForKey:key]这个方法是从缓存里面获取图片,直接从NSCache里面获取,取到了就直接返回,没有取到就从本地磁盘上取[self diskImageForKey:key],源码如下

这个方法的个人理解已经写在截图上面,做了很多事情,有兴趣的可以去看看对应的源码,不做过多介绍。如果从本地取到了图片,就将图片保存在缓存里面,并且回到主线程,将对应的图片对象返回回去,这个地方使用了autoreleasepool,知道是延时释放的作用,但是具体不能理解好处是什么.

    假如从缓存和磁盘都没有取到图片,就从url里面下载图片,使用的是SDWebImageDownloadar的downloadImageWithUrl方法

紧接着的progressCallBack的处理的用处看的不是很明白,接着看下面,设置了请求的超时时间为15s,初始化了Request对象,初始化了继承自NSOperation的SDWebIMageDownloaderOperation对象operation,并且初始化了NSOperationQueue对象,将Operation加入到了queue中,当时我看这个时候,就是没有看到发起请求的地方,后面查阅资料,理解了将operation加入queue中后,会调用对应的start方法,自定义的Operation里面重写了start方法,所以请求的发起是在这个里面,里面还有connection的一些代理方法。继续看SDWebImageDownloaderOperaton的start方法:

截图最后一行的[self.connection start]方法说明了我上面的说法.正常的情况是当应用程序进入后台的时候,所有的下载操作都会终止,这个地方有一个处理就是当应用程序进入后台的时候,这个下载的操作不会立即终止,会执行一段时间才会终止,具体的时间我测试了一下,为175s,基本上是3分钟就会完全终止,这个操作主要是beginBackgroundTaskWithExpirationHandle这个方法来处理的。后面还有一些运行时的一些操作,不是很明白意图,在这里不做介绍。具体的connection请求里面做了什么事情,下一篇文章再介绍(其实主要是我今天还没来得及看后面的,看了再写).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值