SDWebImage源码分析
2015-08-21 18:38
344 查看
-(NSInteger)maxConcurrentDownloads{ return_downloadQueue.maxConcurrentOperationCount; }
SDWebImageManager--单例
-(void)sd_setImageWithURL:(NSURL*)urlplaceholderImage:(UIImage*)placeholderoptions:(SDWebImageOptions)optionsprogress:(SDWebImageDownloaderProgressBlock)progressBlockcompleted:(SDWebImageCompletionBlock)completedBlock{
1.1id<SDWebImageOperation>operation=[SDWebImageManager.sharedManagerdownloadImageWithURL:urloptions:optionsprogress:progressBlockcompleted:
^(UIImage*image,NSError*error,SDImageCacheTypecacheType,BOOLfinished,NSURL*imageURL)
1.2[selfsd_setImageLoadOperation:operationforKey:@"UIImageViewImageLoad"];
SDWebImageManager 1-(id<SDWebImageOperation>)downloadImageWithURL:(NSURL*)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionWithFinishedBlock)completedBlock{ __blockSDWebImageCombinedOperation*operation=[SDWebImageCombinedOperationnew]; @synchronized(self.runningOperations){ [self.runningOperationsaddObject:operation]; } NSString*key=[selfcacheKeyForURL:url]; operation.cacheOperation=[self.imageCachequeryDiskCacheForKey:key done:^(UIImage*image,SDImageCacheTypecacheType) { if(operation.isCancelled){ 49[self.runningOperationsremoveObject:operation]; return; } if((!image||options&SDWebImageRefreshCached)&&(![self.delegaterespondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)]||[self.delegateimageManager:selfshouldDownloadImageForURL:url])) { if(image&&options&SDWebImageRefreshCached){ dispatch_main_sync_safe(^{ //IfimagewasfoundinthecachebugSDWebImageRefreshCachedisprovided,notifyaboutthecachedimage //ANDtrytore-downloaditinordertoletachancetoNSURLCachetorefreshitfromserver. completedBlock(image,nil,cacheType,YES,url); }); }id<SDWebImageOperation>subOperation=[self.imageDownloaderdownloadImageWithURL:urloptions:downloaderOptionsprogress:progressBlockcompleted:^(UIImage*downloadedImage,NSData*data,NSError*error,BOOLfinished){ if(weakOperation.isCancelled){ //Donothingiftheoperationwascancelled //See#699formoredetails //ifwewouldcallthecompletedBlock,therecouldbearaceconditionbetweenthisblockandanothercompletedBlockforthesameobject,soifthisoneiscalledsecond,wewilloverwritethenewdata } elseif(error){ 88completedBlock(nil,error,SDImageCacheTypeNone,finished,url); 94 [self.failedURLsaddObject:url]; 97} else{ BOOLcacheOnDisk=!(options&SDWebImageCacheMemoryOnly); if(options&SDWebImageRefreshCached&&image&&!downloadedImage){ //ImagerefreshhittheNSURLCachecache,donotcallthecompletionblock } //NOTE:Wedon'tcalltransformDownloadedImagedelegatemethodonanimatedimagesasmosttransformationcodewouldmangleit elseif(downloadedImage&&!downloadedImage.images&&[self.delegaterespondsToSelector:@selector(imageManager:transformDownloadedImage:withURL:)]){ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0),^{ UIImage*transformedImage=[self.delegateimageManager:selftransformDownloadedImage:downloadedImagewithURL:url]; if(transformedImage&&finished){ BOOLimageWasTransformed=![transformedImageisEqual:downloadedImage]; [self.imageCachestoreImage:transformedImagerecalculateFromImage:imageWasTransformedimageData:dataforKey:keytoDisk:cacheOnDisk]; } completedBlock(transformedImage,nil,SDImageCacheTypeNone,finished,url); }); } else{ if(downloadedImage&&finished){ [self.imageCachestoreImage:downloadedImagerecalculateFromImage:NOimageData:dataforKey:keytoDisk:cacheOnDisk]; } completedBlock(downloadedImage,nil,SDImageCacheTypeNone,finished,url); } } if(finished){ [self.runningOperationsremoveObject:operation]; } }]; operation.cancelBlock=^{ [subOperationcancel]; [self.runningOperationsremoveObject:weakOperation]; }; } elseif(image){ completedBlock(image,nil,cacheType,YES,url); [self.runningOperationsremoveObject:operation]; } else{ //Imagenotincacheanddownloaddisallowedbydelegate completedBlock(nil,nil,SDImageCacheTypeNone,YES,url); [self.runningOperationsremoveObject:operation]; } }]; returnoperation; }
SDImageCache 1-(NSOperation*)queryDiskCacheForKey:(NSString*)keydone:(SDWebImageQueryCompletedBlock)doneBlock{ //Firstcheckthein-memorycache... UIImage*image=[selfimageFromMemoryCacheForKey:key]; if(image){ doneBlock(image,SDImageCacheTypeMemory); returnnil; } NSOperation*operation=[NSOperationnew]; dispatch_async(self.ioQueue,^{ if(operation.isCancelled){ return; } @autoreleasepool{ UIImage*diskImage=[selfdiskImageForKey:key]; if(diskImage){ CGFloatcost=diskImage.size.height*diskImage.size.width*diskImage.scale; [self.memCachesetObject:diskImageforKey:keycost:cost]; } dispatch_async(dispatch_get_main_queue(),^{ doneBlock(diskImage,SDImageCacheTypeDisk); }); } }); returnoperation; }
SDWebImageDownloader -(id<SDWebImageOperation>)downloadImageWithURL:(NSURL*)urloptions:(SDWebImageDownloaderOptions)optionsprogress:(SDWebImageDownloaderProgressBlock)progressBlockcompleted:(SDWebImageDownloaderCompletedBlock)completedBlock{ __blockSDWebImageDownloaderOperation*operation; [selfaddProgressCallback:progressBlockandCompletedBlock:completedBlockforURL:urlcreateCallback:^{ timeoutInterval=15.0; //Inordertopreventfrompotentialduplicatecaching(NSURLCache+SDImageCache)wedisablethecacheforimagerequestsiftoldotherwise NSMutableURLRequest*request=[[NSMutableURLRequestalloc]initWithURL:url cachePolicy:(options&SDWebImageDownloaderUseNSURLCache?NSURLRequestUseProtocolCachePolicy:NSURLRequestReloadIgnoringLocalCacheData)
timeoutInterval:timeoutInterval];operation=[[SDWebImageDownloaderOperationalloc]initWithRequest:requestoptions:optionsprogress:^(NSIntegerreceivedSize,NSIntegerexpectedSize){SDWebImageDownloaderProgressBlockcallback=callbacks[kProgressCallbackKey];if(callback)callback(receivedSize,expectedSize);}completed:^(UIImage*image,NSData*data,NSError*error,BOOLfinished)SDWebImageDownloaderCompletedBlockcallback=callbacks[kCompletedCallbackKey];if(callback)callback(image,data,error,finished);}cancelled:^{[sselfremoveCallbacksForURL:url];}];[wself.downloadQueueaddOperation:operation];[wself.lastAddedOperationaddDependency:operation];}];returnoperation;}
-(void)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock andCompletedBlock:(SDWebImageDownloaderCompletedBlock)completedBlock forURL:(NSURL*)urlcreateCallback:(SDWebImageNoParamsBlock)createCallback { dispatch_barrier_sync(self.barrierQueue,^{ BOOLfirst=NO; if(!self.URLCallbacks[url]){ self.URLCallbacks[url]=[NSMutableArraynew];//第一次请求该url,新建URLCallbacks数组 first=YES;//标示是第一次 } //HandlesingledownloadofsimultaneousdownloadrequestforthesameURL NSMutableArray*callbacksForURL=self.URLCallbacks[url]; NSMutableDictionary*callbacks=[NSMutableDictionarynew]; if(progressBlock)callbacks[kProgressCallbackKey]=[progressBlockcopy];//保存progressBlock if(completedBlock)callbacks[kCompletedCallbackKey]=[completedBlockcopy];//保存completedBlock [callbacksForURLaddObject:callbacks];//保存至URLCallbacks self.URLCallbacks[url]=callbacksForURL;保存至self.URLCallbacks if(first){ createCallback();//第一次请求该url,执行createCallback } }); }
相关文章推荐
- 【读书笔记】iOS-写代码注意事项
- 我觉得还是好好写博客
- Android自定义控件<迅雷进度条>
- 用VBS控制鼠标,在Excel2010、2013,64位中
- Android Api Demos登顶之路(四十二)Fragment-->Nesting Tabs
- Dapper/SqlMapper映射对应问题
- hdoj 5311 Hidden String 【KMP + 暴力】
- JMS - QueueBrowser
- LightOJ Harmonic Number 1234【技巧】
- MVC 子对象数据传递
- java的自动装箱与拆箱
- struts2学习笔记(四)拦截器与拦截器栈
- Linux命令(5)
- linux下实现mysql主主互备模式配置过程
- USACO 2009 Feb Gold 3.Revamping Trails
- POJ 3281
- C++ Primer 5e chapter 10.1
- 【LeetCode】(7)Reverse Integer(Easy)
- springmvc学习笔记(三)一个Controller中实现多个方法
- 开发笔记-Hibernate