SDWebImage源码解读之SDWebImageDownloader.docx

上传人:b****7 文档编号:24004494 上传时间:2023-05-23 格式:DOCX 页数:24 大小:23.79KB
下载 相关 举报
SDWebImage源码解读之SDWebImageDownloader.docx_第1页
第1页 / 共24页
SDWebImage源码解读之SDWebImageDownloader.docx_第2页
第2页 / 共24页
SDWebImage源码解读之SDWebImageDownloader.docx_第3页
第3页 / 共24页
SDWebImage源码解读之SDWebImageDownloader.docx_第4页
第4页 / 共24页
SDWebImage源码解读之SDWebImageDownloader.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

SDWebImage源码解读之SDWebImageDownloader.docx

《SDWebImage源码解读之SDWebImageDownloader.docx》由会员分享,可在线阅读,更多相关《SDWebImage源码解读之SDWebImageDownloader.docx(24页珍藏版)》请在冰豆网上搜索。

SDWebImage源码解读之SDWebImageDownloader.docx

SDWebImage源码解读之SDWebImageDownloader

SDWebImage源码解读之SDWebImageDownloader

SDWebImageDownloader这个类非常简单,作者的设计思路也很清晰,但是我想在这说点题外话。

如果有人问你:

你怎么看待编程这件事?

你怎么回答。

这个问题是我在看这个类的时候,忽然出现在我脑子中的。

我突然意识到,其实不管是函数还是属性,他们都是数据。

我们编写的所有程序都是在处理数据。

函数本身也是一种特殊的数据。

真正难的是生产数据的这一过程。

举个例子,给你一堆菜籽,要求生产出油来。

怎么办?

我们首先为这个任务设计一个函数:

-(油)用菜籽生产油(菜籽);

这就是我们最外层的函数,也应该是我们最开始想到的函数。

然后经过我们的研究发现,这个生产过程很复杂,必须分工合作才能实现。

于是我们把这个任务分割为好几个小任务:

1.-(干净的菜籽)取出杂质(菜籽);

2.-(炒熟的菜籽)把菜籽炒一下(干净的菜籽);

3.-(蒸了的菜籽)把菜籽蒸一下(炒熟的菜籽);

4.-(捆好的菜籽)把菜籽包捆成一块(蒸了的菜籽);

5.-(油)撞击菜籽包(捆好的菜籽);

大家有没有发现,整个榨油的过程就是对数据的处理。

这一点其实很重要。

如果没有把-(油)用菜籽生产油(菜籽);这一任务进行拆分,我们就会写出复杂无比的函数。

那么就有人要问了,只要实现这个功能就行了呗。

其实这往往是写不出好代码的原因。

整个任务的设计应该是事先就设计好的。

任务被分割成更小更简单的部分,然后再去实现这些最小的任务,不应该是编写边分割任务,往往临时分割的任务(也算是私有函数吧)没有最正确的界限。

有了上边合理的分工之后呢,我们就可以进行任务安排了。

我们回到现实开发中来。

上边5个子任务的难度是不同的。

有的人可能基础比较差,那么让他去干筛菜籽这种体力活,应该没问题。

那些炒或者蒸的子任务是要掌握火候的,也就是说有点技术含量。

那么就交给能胜任这项工作的人去做。

所有的这一切,我们只要事先定义好各自的生产结果就行了,完全不影响每个程序的执行。

怎么样?

大家体会到这种编程设计的好处了吗?

我还可以进行合并,把炒和煮合成一个小组,完全可行啊。

好了这方面的思考就说这么多吧。

如果我想买煮熟了的菜籽,是不是也很简单?

有的人用原始的撞击菜籽包榨油,有的人却用最先进的仪器榨油,这就是编程技术和知识深度的区别啊。

SDWebImageDownloaderOptions

言归正传,当我们需要给某个功能添加Options的时候,一般使用枚举来实现。

我们先看看支持的选项:

typedefNS_OPTIONS(NSUInteger,SDWebImageDownloaderOptions){

SDWebImageDownloaderLowPriority=1<<0,

SDWebImageDownloaderProgressiveDownload=1<<1,//带有进度

SDWebImageDownloaderUseNSURLCache=1<<2,//使用URLCache

SDWebImageDownloaderIgnoreCachedResponse=1<<3,//不缓存响应

SDWebImageDownloaderContinueInBackground=1<<4,//支持后台下载

SDWebImageDownloaderHandleCookies=1<<5,//使用Cookies

SDWebImageDownloaderAllowInvalidSSLCertificates=1<<6,//允许验证SSL

SDWebImageDownloaderHighPriority=1<<7,//高权限

SDWebImageDownloaderScaleDownLargeImages=1<<8,//裁剪大图片

};

这里提供了这么几种不同的选项,大家可以根据自己的需求选个合适的选项。

这里作者使用了掩码。

比如说,1<<1,表示把1左移一位,我们把1携程二进制为:

00000001,那么左移一位后就是:

00000010转成10进制后就是2,也就是说左移一位表示在原来的值上乘以2。

再举个例子,当判断self.option是否是SDWebImageDownloaderIgnoreCachedResponse选项时,应该这么判断:

self.option&SDWebImageDownloaderIgnoreCachedResponse

SDWebImageDownloaderExecutionOrder

SDWebImageDownloaderExecutionOrder定义了数据被调用的顺序。

按照一般的想法。

下载应该按照数据放入队列的顺序依次进行,但也支持后进先出这种方式。

一个下载管理器应该这样管理下载,肯定有一个下载列表,我们可以假定这个列表保存在一个数组中,正常情况下我们应该每次取出数组中第1个元素来下载,这就是FIFO(先进先出)。

那么我们要改为LIFO(后进先出),应该是针对某一个下载的,不应该是把取出数据的顺序改为从数组的最后一个元素取出。

typedefNS_ENUM(NSInteger,SDWebImageDownloaderExecutionOrder){

/**

*Defaultvalue.Alldownloadoperationswillexecuteinqueuestyle(first-in-first-out).

*/

SDWebImageDownloaderFIFOExecutionOrder,

/**

*Alldownloadoperationswillexecuteinstackstyle(last-in-first-out).

*/

SDWebImageDownloaderLIFOExecutionOrder

};

但是我有一个疑问,如果我只是想暂停某一个下载,我该怎么办呢?

如果直接取消,那么点击继续的时候,要重新开启下载,肯定影响体验。

这一点跟使用数组管理任务有点不同。

辅助部分

externNSString*_NonnullconstSDWebImageDownloadStartNotification;

externNSString*_NonnullconstSDWebImageDownloadStopNotification;

通过extern,我们就能够使用其他文件的代码。

typedefvoid(^SDWebImageDownloaderProgressBlock)(NSIntegerreceivedSize,NSIntegerexpectedSize,NSURL*_NullabletargetURL);

typedefvoid(^SDWebImageDownloaderCompletedBlock)(UIImage*_Nullableimage,NSData*_Nullabledata,NSError*_Nullableerror,BOOLfinished);

命名Block

typedefNSDictionarySDHTTPHeadersDictionary;

typedefNSMutableDictionarySDHTTPHeadersMutableDictionary;

命名字典

typedefSDHTTPHeadersDictionary*_Nullable(^SDWebImageDownloaderHeadersFilterBlock)(NSURL*_Nullableurl,SDHTTPHeadersDictionary*_Nullableheaders);

这个block允许我们自定义请求头,通过Block传值,有一定的优点,我们可以拿到一些参数,然后在加工成我们需要的数据,最后返回。

SDWebImageDownloadToken

SDWebImageDownloadToken作为每一个下载的唯一身份标识,SDWebImageDownloader和我们平时开发中的下载还是又不一样的地方的,它弱化了下载过程,比较强调的是下载结果。

不支持断点下载(当然这可能没有必要)。

如果我们需要设计一个自己的下载管理者,我们就应该设计一个类似SDWebImageDownloadToken这样的下载对象封装类,我需要的所有信息,都能在这个对象中获取,大家如果有兴趣,可以看看MCDownloadManager.

/**

*Atokenassociatedwitheachdownload.Canbeusedtocanceladownload

*/

@interfaceSDWebImageDownloadToken:

NSObject

@property(nonatomic,strong,nullable)NSURL*url;

@property(nonatomic,strong,nullable)iddownloadOperationCancelToken;

@end

SDWebImageDownloader.h

/**

*Decompressingimagesthataredownloadedandcachedcanimproveperformancebutcanconsumelotofmemory.

*DefaultstoYES.SetthistoNOifyouareexperiencingacrashduetoexcessivememoryconsumption.

*/

@property(assign,nonatomic)BOOLshouldDecompressImages;

/**

*Themaximumnumberofconcurrentdownloads

*/

@property(assign,nonatomic)NSIntegermaxConcurrentDownloads;

/**

*Showsthecurrentamountofdownloadsthatstillneedtobedownloaded

*/

@property(readonly,nonatomic)NSUIntegercurrentDownloadCount;

 

/**

*Thetimeoutvalue(inseconds)forthedownloadoperation.Default:

15.0.

*/

@property(assign,nonatomic)NSTimeIntervaldownloadTimeout;

 

/**

*Changesdownloadoperationsexecutionorder.Defaultvalueis`SDWebImageDownloaderFIFOExecutionOrder`.

*/

@property(assign,nonatomic)SDWebImageDownloaderExecutionOrderexecutionOrder;

/**

*Singletonmethod,returnsthesharedinstance

*

*@returnglobalsharedinstanceofdownloaderclass

*/

+(nonnullinstancetype)sharedDownloader;

/**

*SetthedefaultURLcredentialtobesetforrequestoperations.

*/

@property(strong,nonatomic,nullable)NSURLCredential*urlCredential;

/**

*Setusername

*/

@property(strong,nonatomic,nullable)NSString*username;

/**

*Setpassword

*/

@property(strong,nonatomic,nullable)NSString*password;

/**

*SetfiltertopickheadersfordownloadingimageHTTPrequest.

*

*Thisblockwillbeinvokedforeachdownloadingimagerequest,returned

*NSDictionarywillbeusedasheadersincorrespondingHTTPrequest.

*/

@property(nonatomic,copy,nullable)SDWebImageDownloaderHeadersFilterBlockheadersFilter;

初始化方法

/**

*Createsaninstanceofadownloaderwithspecifiedsessionconfiguration.

**Note*:

`timeoutIntervalForRequest`isgoingtobeoverwritten.

*@returnnewinstanceofdownloaderclass

*/

-(nonnullinstancetype)initWithSessionConfiguration:

(nullableNSURLSessionConfiguration*)sessionConfigurationNS_DESIGNATED_INITIALIZER;

我们都知道:

一个NSURLSession会话,使用NSURLSessionConfiguration进行配置,利用这一点,我们在设计自己的网络框架的时候,可以参考NSURLSessionConfiguration。

暴露少量的属性来配置网络请求,后期维护起来也比较容易。

使用NS_DESIGNATED_INITIALIZER强调该方法是建议的初始化方法。

其他的方法

/**

*SetavalueforaHTTPheadertobeappendedtoeachdownloadHTTPrequest.

*

*@paramvalueThevaluefortheheaderfield.Use`nil`valuetoremovetheheader.

*@paramfieldThenameoftheheaderfieldtoset.

*/

-(void)setValue:

(nullableNSString*)valueforHTTPHeaderField:

(nullableNSString*)field;

/**

*ReturnsthevalueofthespecifiedHTTPheaderfield.

*

*@returnThevalueassociatedwiththeheaderfieldfield,or`nil`ifthereisnocorrespondingheaderfield.

*/

-(nullableNSString*)valueForHTTPHeaderField:

(nullableNSString*)field;

/**

*Setsasubclassof`SDWebImageDownloaderOperation`asthedefault

*`NSOperation`tobeusedeachtimeSDWebImageconstructsarequest

*operationtodownloadanimage.

*

*@paramoperationClassThesubclassof`SDWebImageDownloaderOperation`toset

*asdefault.Passing`nil`willrevertto`SDWebImageDownloaderOperation`.

*/

-(void)setOperationClass:

(nullableClass)operationClass;

/**

*CreatesaSDWebImageDownloaderasyncdownloaderinstancewithagivenURL

*

*Thedelegatewillbeinformedwhentheimageisfinishdownloadedoranerrorhashappen.

*

*@seeSDWebImageDownloaderDelegate

*

*@paramurlTheURLtotheimagetodownload

*@paramoptionsTheoptionstobeusedforthisdownload

*@paramprogressBlockAblockcalledrepeatedlywhiletheimageisdownloading

*@notetheprogressblockisexecutedonabackgroundqueue

*@paramcompletedBlockAblockcalledoncethedownloadiscompleted.

*Ifthedownloadsucceeded,theimageparameterisset,incaseoferror,

*errorparameterissetwiththeerror.ThelastparameterisalwaysYES

*ifSDWebImageDownloaderProgressiveDownloadisn'tuse.Withthe

*SDWebImageDownloaderProgressiveDownloadoption,thisblockiscalled

*repeatedlywiththepartialimageobjectandthefinishedargumentsettoNO

*beforetobecalledalasttimewiththefullimageandfinishedargument

*settoYES.Incaseoferror,thefinishedargumentisalwaysYES.

*

*@returnAtoken(SDWebImageDownloadToken)thatcanbepassedto-cancel:

tocancelthisoperation

*/

-(nullableSDWebImageDownloadToken*)downloadImageWithURL:

(nullableNSURL*)url

options:

(SDWebImageDownloaderOptions)options

progress:

(nullableSDWebImageDownloaderProgressBlock)progressBlock

completed:

(nullableSDWebImageDownloaderCompletedBlock)completedBlock;

/**

*Cancelsadownloadthatwaspreviouslyqueuedusing-downloadImageWithURL:

options:

progress:

completed:

*

*@paramtokenThetokenreceivedfrom-downloadImageWithURL:

options:

progress:

completed:

thatshouldbecanceled.

*/

-(void)cancel:

(nullableSDWebImageDownloadToken*)token;

/**

*Setsthedownloadqueuesuspensionstate

*/

-(void)setSuspended:

(BOOL)suspended;

/**

*Cancelsalldownloadoperationsinthequeue

*/

-(void)cancelAllDownloads;

SDWebImageDownloader.m

@property(strong,nonatomic,nonnull)NSOperationQueue*downloadQueue;

@property(weak,nonatomic,nullable)NSOperation*lastAddedOperation;

@property(assign,nonatomic,nullable)ClassoperationClass;

@property(strong,nonatomic,nonnull)NSMutableDictionary*URLOperations;

@property(strong,nonatomic,nullable)SDHTTPHeadersMutableDictionary*HTTPHeaders;

//Thisqueueisusedtoserializethehandlingofthenetworkresponsesofallthedownloadoperationinasinglequeue

@property(SDDispatchQueueSetterSementics,nonatomic,nullable)dispatch_queue_tbarrierQueue;

//Thesessioninwhichdatataskswillrun

@property(strong,nonatomic)NS

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1