>

SDWebImage-SDWebImageManger澳门新葡亰平台游戏

- 编辑:澳门新葡亰平台游戏 -

SDWebImage-SDWebImageManger澳门新葡亰平台游戏

SDWebImage

  • 在SDWebImageManager 管理器中设置须求头参数
  • 在下载器中启用cookes
SDWebImageManager *sdmanger = [SDWebImageManager sharedManager]; [sdmanger.imageDownloader setValue:@"true" forHTTPHeaderField:@"thumbnail"]; SDWebImageDownloader *downLoader = [SDWebImageDownloader sharedDownloader]; [downLoader downloadImageWithURL:@"111" options:SDWebImageDownloaderHandleCookies progress:^(NSInteger receivedSize, NSInteger expectedSize) { } completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { }];

// 内部实现还是和上边一样 。 [imageView sd_setImageWithURL:@"" placeholderImage:@"" options:SDWebImageHandleCookies];
  • SDWebImageRetryFailed = 1 << 0, 私下认可情况下,假诺二个url在下载的时候失利了,那么那个url会被插手黑名单并且library不会尝试再度下载,这么些flag会阻止library把停业的url到场黑名单(轻巧的话假诺接纳了那一个flag,那么就算某些url下载战败了,sdwebimage依然会尝试再一次下载他.)

  • SDWebImageLowPriority = 1 << 1, 暗中认可意况下,图片会在竞相发生的时候下载(举例你滑动tableview的时候),这几个flag会禁止那么些特点,导致的结果就是在scrollview减速的时候才会起来下载(也正是您滑动的时候scrollview不下载,你手从荧屏上移走,scrollview早先减速的时候才会初始下载图片)能够扩充UI的流畅度

  • SDWebImageCacheMemoryOnly = 1 << 2,禁止磁盘缓存

  • SDWebImageProgressiveDownload = 1 << 3,渐进展现实时的下载图片 ,暗许是只展现完整下载后的图 。

  • SDWebImageRefreshCached = 1 << 4,即便有缓存 ,也再度从远程必要图片 。这年缓存由NSU揽胜LCache 管理。

  • SDWebImageContinueInBackground = 1 << 5,ios4以上,当app到后台 ,央浼扩张后台下载的时间 。

  • SDWebImageHandleCookies = 1 << 6,下载时,允许利用cookes NSMutableUWranglerLRequest.HTTPShouldHandleCookies = YES;

  • SDWebImageAllowInvalidSSLCertificates = 1 << 7,启用允许不受信任的SSL证书。 不引入应用

  • SDWebImageHighPriority = 1 << 8, 暗中同意情况下,image在装载的时候是依据他们在队列中的顺序装载的.那几个flag会把她们活动到行列的前端,并且及服装载并非等到近期队列装载的时候再装载.

  • SDWebImageDelayPlaceholder = 1 << 9,

  • SDWebImageTransformAnimatedImage = 1 << 10, 是否transform图片

实践的实际正是SDWebImageManager 。他会绑定一个下载器约等于SDWebImageDownloader和一个缓存SDImageCache.前面包车型大巴马虎应该是讲你能够从来利用二个别样上下文遭遇的SDWebImageManager,并不是一味限于三个UIView.

 SDWebImageManager *manager = [SDWebImageManager sharedManager]; [manager downloadImageWithURL:imageURL options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if  { // do something with image }];
  • 驷比不上舌职能是当缓存里未有发觉某张图纸的缓存时,是不是选拔下载这张图纸,能够选用no,那么sdwebimage在缓存中从不找到那张图片的时候不会接纳下载

     - imageManager:(SDWebImageManager *)imageManager shouldDownloadImageForURL:imageURL;
    
  • 在图片下载实现并且还尚无投入磁盘缓存只怕内部存款和储蓄器缓存的时候就transform这么些图片.那几个法子是在异步线程实践的,防治阻塞主线程.

     - (UIImage *)imageManager:(SDWebImageManager *)imageManager transformDownloadedImage:(UIImage *)image withURL:imageURL;
    
  • 那么些cacheKeyFilter是干嘛的呢?很轻易.1他是贰个block.2.那么些block的魔法正是生成一个image的key.因为sdwebimage的缓存原理你能够算作是一个字典,每贰个字典的value就是一张image,那么这几个value对应的key是何许呢?正是cacheKeyFilter依据有个别法则对那几个图片的url做一些操作生成的.

     typedef NSString *(^SDWebImageCacheKeyFilterBlock)(NSURL *url); @property (nonatomic, copy) SDWebImageCacheKeyFilterBlock cacheKeyFilter;
    
[[SDWebImageManager sharedManager] setCacheKeyFilter:^(NSURL *url) { url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path]; return [url absoluteString];}];
  • 以此格局首要正是SDWebImage下载图片的章程了.
  • 首先个参数是必得求的,便是image的url
  • 第四个参数便是我们地方的Options,你能够定制化五光十色的操作.详细情形参上.
  • 其八个参数是三个回调block,用于图片在下载进程中的回调.
  • 第八个参数是多少个下载完毕的回调.会在图片下载达成后回调.
  • 再次回到值是三个NSObject类,并且这些NSObject类是conforming五个商谈那么些公约叫做SDWebImageOperation,这些左券很粗大略,就是一个cancel掉operation的合同.
 -downloadImageWithURL:url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionWithFinishedBlock)completedBlock;
  • 注销掉当前有所的下载图片的operation

     - cancelAll;
    
  • 将图片存入cache的诀要,类似于字典的setValue: forKey:

     - saveImageToCache:(UIImage *)image forURL:url;
    
  • check一下是不是有三个依旧多少个operation正在施行(轻便的话正是check是否有图表在下载)

     - isRunning;
    
  • 检验多少个image是不是早已被缓存到磁盘(是不是存且仅存在disk里).

     - diskImageExistsForURL:url;
    
  • 一经济检察测到图片已经被缓存,那么实践回调block.那一个block会永世实践在主线程.也正是你可以在这些回调block里更新ui.(也便是用三个url 来得到缓存的图片 ,并且那么些blcok是在主线程)

     - cachedImageExistsForURL:url completion:(SDWebImageCheckCacheCompletionBlock)completionBlock;
    
  • 透过image的url重返image存在缓存里的key.为何不间接把图纸的url当做image的key来行使呢?而是非要对url做一些管理技艺当做key.作者的分解是,作者也不老聃楚.大概为了防止重复吧.

     - (NSString *)cacheKeyForURL:url;
    
- downloadImageWithURL:url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionWithFinishedBlock)completedBlock { // Invoking this method without a completedBlock is pointless NSAssert(completedBlock != nil, @"If you mean to prefetch the image, use -[SDWebImagePrefetcher prefetchURLs] instead"); // Very common mistake is to send the URL using NSString object instead of NSURL. For some strange reason, XCode won't // throw any warning for this type mismatch. Here we failsafe this error by allowing URLs to be passed as NSString. if ([url isKindOfClass:NSString.class]) { url = [NSURL URLWithString:(NSString *)url]; } // Prevents app crashing on argument type error like sending NSNull instead of NSURL if (![url isKindOfClass:NSURL.class]) { url = nil; } __block SDWebImageCombinedOperation *operation = [SDWebImageCombinedOperation new]; __weak SDWebImageCombinedOperation *weakOperation = operation; BOOL isFailedUrl = NO; // 创建一个互斥锁防止现在有别的线程修改failedURLs. // 判断这个url是否是fail过的.如果url failed过的那么isFailedUrl就是true @synchronized (self.failedURLs) { isFailedUrl = [self.failedURLs containsObject:url]; } // 如果url不存在那么直接返回一个block,如果url存在.那么继续进行判断. // options与SDWebImageRetryFailed这个option进行按位与操作.判断用户的options里是否有retry这个option. // 如果用户的options里没有retry这个选项并且isFaileUrl 是true.那么就回调一个error的block. if (!url || (!(options & SDWebImageRetryFailed) && isFailedUrl)) { dispatch_main_sync_safe(^{ NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]; completedBlock(nil, error, SDImageCacheTypeNone, YES, url); }); return operation; } // 创建一个互斥锁防止现在有别的线程修改runningOperations. @synchronized (self.runningOperations) { [self.runningOperations addObject:operation]; } NSString *key = [self cacheKeyForURL:url]; // cacheOperation应该是一个用来下载图片并且缓存的operation operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) { // 判断operation这时候有没有执行cancel操作,如果cancel掉了就把这个operation从我们的operation数组里remove掉然后return if (operation.isCancelled) { @synchronized (self.runningOperations) { [self.runningOperations removeObject:operation]; } return; } if ((!image || options & SDWebImageRefreshCached) && (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url])) { if (image && options & SDWebImageRefreshCached) { dispatch_main_sync_safe(^{ // If image was found in the cache bug SDWebImageRefreshCached is provided, notify about the cached image // AND try to re-download it in order to let a chance to NSURLCache to refresh it from server. completedBlock(image, nil, cacheType, YES, url); }); } // download if no image or requested to refresh anyway, and download allowed by delegate // 下面都是判断我们的options里包含哪些SDWebImageOptions,然后给我们的downloaderOptions相应的添加对应的SDWebImageDownloaderOptions. downloaderOptions |= SDWebImageDownloaderLowPriority这种表达式的意思等同于 // downloaderOptions = downloaderOptions | SDWebImageDownloaderLowPriority SDWebImageDownloaderOptions downloaderOptions = 0; if (options & SDWebImageLowPriority) downloaderOptions |= SDWebImageDownloaderLowPriority; if (options & SDWebImageProgressiveDownload) downloaderOptions |= SDWebImageDownloaderProgressiveDownload; if (options & SDWebImageRefreshCached) downloaderOptions |= SDWebImageDownloaderUseNSURLCache; if (options & SDWebImageContinueInBackground) downloaderOptions |= SDWebImageDownloaderContinueInBackground; if (options & SDWebImageHandleCookies) downloaderOptions |= SDWebImageDownloaderHandleCookies; if (options & SDWebImageAllowInvalidSSLCertificates) downloaderOptions |= SDWebImageDownloaderAllowInvalidSSLCertificates; if (options & SDWebImageHighPriority) downloaderOptions |= SDWebImageDownloaderHighPriority; if (image && options & SDWebImageRefreshCached) { // force progressive off if image already cached but forced refreshing downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload; // ignore image read from NSURLCache if image if cached but force refreshing downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse; } // 调用imageDownloader去下载image并且返回执行这个request的download的operation id subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) { if (weakOperation.isCancelled) { // Do nothing if the operation was cancelled // See #699 for more details // if we would call the completedBlock, there could be a race condition between this block and another completedBlock for the same object, so if this one is called second, we will overwrite the new data } else if  { dispatch_main_sync_safe(^{ if (!weakOperation.isCancelled) { completedBlock(nil, error, SDImageCacheTypeNone, finished, url); } }); if (error.code != NSURLErrorNotConnectedToInternet && error.code != NSURLErrorCancelled && error.code != NSURLErrorTimedOut) { @synchronized (self.failedURLs) { [self.failedURLs addObject:url]; } } } else { if ((options & SDWebImageRetryFailed)) { @synchronized (self.failedURLs) { [self.failedURLs removeObject:url]; } } BOOL cacheOnDisk = !(options & SDWebImageCacheMemoryOnly); if (options & SDWebImageRefreshCached && image && !downloadedImage) { // Image refresh hit the NSURLCache cache, do not call the completion block } else if (downloadedImage && (!downloadedImage.images || (options & SDWebImageTransformAnimatedImage)) && [self.delegate respondsToSelector:@selector(imageManager:transformDownloadedImage:withURL:)]) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ UIImage *transformedImage = [self.delegate imageManager:self transformDownloadedImage:downloadedImage withURL:url]; if (transformedImage && finished) { BOOL imageWasTransformed = ![transformedImage isEqual:downloadedImage]; [self.imageCache storeImage:transformedImage recalculateFromImage:imageWasTransformed imageData:data forKey:key toDisk:cacheOnDisk]; } dispatch_main_sync_safe(^{ if (!weakOperation.isCancelled) { completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished, url); } }); }); } else { if (downloadedImage && finished) { [self.imageCache storeImage:downloadedImage recalculateFromImage:NO imageData:data forKey:key toDisk:cacheOnDisk]; } dispatch_main_sync_safe(^{ if (!weakOperation.isCancelled) { completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished, url); } }); } } if  { @synchronized (self.runningOperations) { [self.runningOperations removeObject:operation]; } } }]; operation.cancelBlock = ^{ [subOperation cancel]; @synchronized (self.runningOperations) { [self.runningOperations removeObject:weakOperation]; } }; } else if  { dispatch_main_sync_safe(^{ if (!weakOperation.isCancelled) { completedBlock(image, nil, cacheType, YES, url); } }); @synchronized (self.runningOperations) { [self.runningOperations removeObject:operation]; } } else { // Image not in cache and download disallowed by delegate dispatch_main_sync_safe(^{ if (!weakOperation.isCancelled) { completedBlock(nil, nil, SDImageCacheTypeNone, YES, url); } }); @synchronized (self.runningOperations) { [self.runningOperations removeObject:operation]; } } }]; return operation;} 

- (NSString *)cachedFileNameForKey:(NSString *)key { const char *str = [key UTF8String]; if (str == NULL) { str = ""; } unsigned char r[CC_MD5_DIGEST_LENGTH]; CC_MD5(str, strlen; NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%@", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15], [[key pathExtension] isEqualToString:@""] ? @"" : [NSString stringWithFormat:@".%@", [key pathExtension]]]; return filename;}

- storeImage:(UIImage *)image recalculateFromImage:recalculate imageData:imageData forKey:(NSString *)key toDisk:toDisk { if (!image || !key) { return; } // if memory cache is enabled if (self.shouldCacheImagesInMemory) { NSUInteger cost = SDCacheCostForImage; [self.memCache setObject:image forKey:key cost:cost]; } if  { dispatch_async(self.ioQueue, ^{ NSData *data = imageData; if (image && (recalculate || !data)) {#if TARGET_OS_IPHONE // We need to determine if the image is a PNG or a JPEG // PNGs are easier to detect because they have a unique signature (http://www.w3.org/TR/PNG-Structure.html) // The first eight bytes of a PNG file always contain the following  values: // 137 80 78 71 13 10 26 10 // If the imageData is nil (i.e. if trying to save a UIImage directly or the image was transformed on download) // and the image has an alpha channel, we will consider it PNG to avoid losing the transparency int alphaInfo = CGImageGetAlphaInfo(image.CGImage); BOOL hasAlpha = !(alphaInfo == kCGImageAlphaNone || alphaInfo == kCGImageAlphaNoneSkipFirst || alphaInfo == kCGImageAlphaNoneSkipLast); BOOL imageIsPng = hasAlpha; // But if we have an image data, we will look at the preffix if ([imageData length] >= [kPNGSignatureData length]) { imageIsPng = ImageDataHasPNGPreffix(imageData); } if (imageIsPng) { data = UIImagePNGRepresentation; } else { data = UIImageJPEGRepresentation(image, 1.0); }#else data = [NSBitmapImageRep representationOfImageRepsInArray:image.representations usingType: NSJPEGFileType properties:nil];#endif } [self storeImageDataToDisk:data forKey:key]; }); }}

本文由java编程发布,转载请注明来源:SDWebImage-SDWebImageManger澳门新葡亰平台游戏