您的位置:首页 > 其它

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
}
});
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: