三种开发方法(程序开发的方法)

湘潭网餐饮知识
165

湘潭网小编为大家带来以下内容:

本篇内容介绍了“ios开发中SDWebImage方法怎么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!源码解析

废话不多说看源码。

1:在组件中提供了很多类似这样的方法

- (void)sd_setImageWithURL:(nullable NSURL *)url;- (void)sd_setImageWithURL:(nullable NSURL *)url          placeholderImage:(nullable UIImage *)placeholder;

2:于是乎所有的方法都会调用下面的这个方法

- (void)sd_internalSetImageWithURL:(nullable NSURL *)url                  placeholderImage:(nullable UIImage *)placeholder                           options:(SDWebImageOptions)options                      operationKey:(nullable NSString *)operationKey                     setImageBlock:(nullable SDSetImageBlock)setImageBlock                          progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock                         completed:(nullable SDExternalCompletionBlock)completedBlock

3:下面具体阅读代码 第一行执行的代码

/    SDOperationsDictionary *operationDictionary = [self operationDictionary];        id operations = operationDictionary[key];    if (operations) {        if ([operations isKindOfClass:[NSArray class]]) {            for (id <SDWebImageOperation> operation in operations) {                if (operation) {                    [operation cancel];                }            }        } else if ([operations conformsToProtocol:@protocol(SDWebImageOperation)]){            [(id<SDWebImageOperation>) operations cancel];        }        [operationDictionary removeObjectForKey:key];    }}字典操作

在看一下去字典操作[self operationDictionary]

- (SDOperationsDictionary *)operationDictionary {        SDOperationsDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey);    // 创建成功返回该字典,直接把该字典当做属性返回    if (operations) {        return operations;    }    operations = [NSMutableDictionary dictionary];    objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC);    return operations;}

看到这里我们在返回继续看 这个函数的代码有点长,耐心看完啊。。。

- (void)sd_internalSetImageWithURL:(nullable NSURL *)url                  placeholderImage:(nullable UIImage *)placeholder                           options:(SDWebImageOptions)options                      operationKey:(nullable NSString *)operationKey                     setImageBlock:(nullable SDSetImageBlock)setImageBlock                          progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock                         completed:(nullable SDExternalCompletionBlock)completedBlock {    /    [self sd_cancelImageLoadOperationWithKey:validOperationKey];    objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);            if (!(options & SDWebImageDelayPlaceholder)) {                dispatch_main_async_safe(^{                        [self sd_setImage:placeholder imagedata:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock];        });    }        if (url) {        // check if activityView is enabled or not        if ([self sd_showActivityIndicatorView]) {            [self sd_addActivityIndicator];        }        __weak __typeof(self)wself = self;                id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {            __strong __typeof (wself) sself = wself;            [sself sd_removeActivityIndicator];            if (!sself) {                return;            }            dispatch_main_async_safe(^{                if (!sself) {                    return;                }                if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock) {                    completedBlock(image, error, cacheType, url);                    return;                } else if (image) {                    [sself sd_setImage:image imagedata:data basedOnClassOrViaCustomSetImageBlock:setImageBlock];                    [sself sd_setNeedsLayout];                } else {                    if ((options & SDWebImageDelayPlaceholder)) {                        [sself sd_setImage:placeholder imagedata:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock];                        [sself sd_setNeedsLayout];                    }                }                if (completedBlock && finished) {                    completedBlock(image, error, cacheType, url);                }            });        }];                [self sd_setImageLoadOperation:operation forKey:validOperationKey];    } else {        dispatch_main_async_safe(^{            [self sd_removeActivityIndicator];            if (completedBlock) {                NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];                completedBlock(nil, error, SDImageCacheTypeNone, url);            }        });    }}看一下调用下载函数前的实例化过程

这个loadImageWithURL函数在SDWebImageManager,并且是用单列调用,

+ (nonnull instancetype)sharedManager {    static dispatch_once_t once;    static id instance;    dispatch_once(&once, ^{        instance = [self new];    });    return instance;}- (nonnull instancetype)init {        SDImageCache *cache = [SDImageCache sharedImageCache];    SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];    return [self initWithCache:cache downloader:downloader];}- (nonnull instancetype)initWithCache:(nonnull SDImageCache *)cache downloader:(nonnull SDWebImageDownloader *)downloader {    if ((self = [super init])) {        _imageCache = cache;        _imageDownloader = downloader;                _failedURLs = [NSMutableSet new];        _runningOperations = [NSMutableArray new];    }    return self;}

上面都是初始化的操作,然后看下面的函数

- (id <SDWebImageOperation>)loadImageWithURL:(nullable NSURL *)url                                     options:(SDWebImageOptions)options                                    progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock                                   completed:(nullable SDInternalCompletionBlock)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;    if (url) {                @synchronized (self.failedURLs) {            isFailedUrl = [self.failedURLs containsObject:url];        }    }        if (url.absoluteString.length == 0 || (!(options & SDWebImageRetryFailed) && isFailedUrl)) {        [self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil] url:url];        return operation;    }        @synchronized (self.runningOperations) {        [self.runningOperations addObject:operation];    }        NSString *key = [self cacheKeyForURL:url];        operation.cacheOperation = [self.imageCache queryCacheOperationForKey:key done:^(UIImage *cachedImage, NSData *cachedData, SDImageCacheType cacheType) {                if (operation.isCancelled) {            [self safelyRemoveOperationFromRunning:operation];            return;        }                //条件1:在缓存中没有找到图片或者options选项里面包含了SDWebImageRefreshCached(这两项都需要进行请求网络图片的)        //条件2:代理允许下载,SDWebImageManagerDelegate的delegate不能响应imageManager:shouldDownloadImageForURL:方法或者能响应方法且方法返回值为YES.也就是没有实现这个方法就是允许的,如果实现了的话,返回YES才是允许        if ((!cachedImage || options & SDWebImageRefreshCached) &&            (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url])) {            //如果在缓存中找到了image且options选项包含SDWebImageRefreshCached,先在主线程完成一次回调,使用的是缓存中找的图片            if (cachedImage && options & SDWebImageRefreshCached) {                // If image was found in the cache but 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.                                [self callCompletionBlockForOperation:weakOperation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url];            }            // 如果没有在缓存中找到image 或者设置了需要请求服务器刷新的选项,则仍需要下载            // download if no image or requested to refresh anyway, and download allowed by delegate            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 (options & SDWebImageScaleDownLargeImages) downloaderOptions |= SDWebImageDownloaderScaleDownLargeImages;            if (cachedImage && options & SDWebImageRefreshCached) {                // force progressive off if image already cached but forced refreshing                // 如果image已经被缓存但是设置了需要请求服务器刷新的选项,强制关闭渐进式选项                downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;                // ignore image read from NSURLCache if image if cached but force refreshing                // 如果image已经被缓存但是设置了需要请求服务器刷新的选项,忽略从NSURLCache读取的image                downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;            }                                    SDWebImageDownloadToken *subOperationToken = [self.imageDownloader downloadImageWithURL:url                                                                                            options:downloaderOptions                                                                                           progress:progressBlock                                                                                          completed:^(UIImage *downloadedImage,                                                                                                      NSData *downloadedData,                                                                                                      NSError *error,                                                                                                      BOOL finished) {                __strong __typeof(weakOperation) strongOperation = weakOperation;                                                                                                              if (!strongOperation || strongOperation.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                    //如果我们调用completedBlock,这个block会和另外一个completedBlock争夺一个对象,因此这个block被调用后会覆盖新的数据                } else if (error) {                    //进行完成回调                    [self callCompletionBlockForOperation:strongOperation completion:completedBlock error:error url:url];                    if (   error.code != NSURLErrorNotConnectedToInternet                        && error.code != NSURLErrorCancelled                        && error.code != NSURLErrorTimedOut                        && error.code != NSURLErrorInternationalRoamingOff                        && error.code != NSURLErrorDataNotAllowed                        && error.code != NSURLErrorCannotFindHost                        && error.code != NSURLErrorCannotConnectToHost) {                        //将失败的url添加到failedURLS的set中去                        @synchronized (self.failedURLs) {                            [self.failedURLs addObject:url];                        }                    }                }                else {                    //如果有重试状态,将url从失败列表中移除                    if ((options & SDWebImageRetryFailed)) {                        @synchronized (self.failedURLs) {                            [self.failedURLs removeObject:url];                        }                    }                    BOOL cacheOnDisk = !(options & SDWebImageCacheMemoryOnly);                    //options包含了SDWebImageRefreshCached选项,且缓存中找到了image且没有下载成功                    if (options & SDWebImageRefreshCached && cachedImage && !downloadedImage) {                        // Image refresh hit the NSURLCache cache, do not call the completion block                    } else if (                               //图片下载成功并且 设置了需要变形Image的选项且变形的代理方法已经实现                               downloadedImage &&                               (!downloadedImage.images || (options & SDWebImageTransformAnimatedImage)) &&[self.delegate respondsToSelector:@selector(imageManager:transformDownloadedImage:withURL:)]                               ) {                                                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{                            //调用代理方法完成图片transform                            UIImage *transformedImage = [self.delegate imageManager:self transformDownloadedImage:downloadedImage withURL:url];                            if (transformedImage && finished) {                                BOOL imageWasTransformed = ![transformedImage isEqual:downloadedImage];                                // pass nil if the image was transformed, so we can recalculate the data from the image                                //对已经transform的图片进行缓存                                [self.imageCache storeImage:transformedImage imagedata:(imageWasTransformed ? nil : downloadedData) forKey:key toDisk:cacheOnDisk completion:nil];                            }                                                        [self callCompletionBlockForOperation:strongOperation completion:completedBlock image:transformedImage data:downloadedData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url];                        });                    } else {                        //如果没有图片transform的需求并且图片下载完成且图片存在就直接缓存                        if (downloadedImage && finished) {                            [self.imageCache storeImage:downloadedImage imagedata:downloadedData forKey:key toDisk:cacheOnDisk completion:nil];                        }                                                [self callCompletionBlockForOperation:strongOperation completion:completedBlock image:downloadedImage data:downloadedData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url];                    }                }                                if (finished) {                    [self safelyRemoveOperationFromRunning:strongOperation];                }            }];                        operation.cancelBlock = ^{                [self.imageDownloader cancel:subOperationToken];                __strong __typeof(weakOperation) strongOperation = weakOperation;                [self safelyRemoveOperationFromRunning:strongOperation];            };            //在缓存中找到图片(代理不允许下载 或者没有设置SDWebImageRefreshCached选项  满足至少一项)        } else if (cachedImage) {            __strong __typeof(weakOperation) strongOperation = weakOperation;            [self callCompletionBlockForOperation:strongOperation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url];            [self safelyRemoveOperationFromRunning:operation];        } else {            //缓存中没有扎到图片且代理不允许下载            // Image not in cache and download disallowed by delegate            __strong __typeof(weakOperation) strongOperation = weakOperation;            [self callCompletionBlockForOperation:strongOperation completion:completedBlock image:nil data:nil error:nil cacheType:SDImageCacheTypeNone finished:YES url:url];            [self safelyRemoveOperationFromRunning:operation];        }    }];    return operation;}

这个函数就进入了SDWebimage缓存的策略了。

先说一下他的这一个策略缓存。

*1:大家都是SDWebiamge都是先从缓存上查找,如果有就直接显示

*2:如果不存在就在沙盒中查找 

*2.1如果存在,则把沙盒中的图片添加到imageCache中,取出显示 

*2.2 如果不存在在显示占位图,根据URL在operationCache是否存在下载操作 

*2.2.1 如果存在,说明该图片正在下载。

*2.2.2如果不存在,创建图片下载操作,放到operationCache中

* 2.3 下载完成,将当前操作队列从operationCache中移除。并将下载的图片的添加在imageCache中。显示

先慢慢体会一下。。。(停留30秒)

开始进入查找函数- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key done:(nullable SDCacheQueryCompletedBlock)doneBlock {            if (!key) {        if (doneBlock) {            doneBlock(nil, nil, SDImageCacheTypeNone);        }        return nil;    }    // 先检查缓存--内存上的数据    // First check the in-memory cache...    UIImage *image = [self imageFromMemoryCacheForKey:key];    if (image) {                NSData *diskData = nil;        if ([image isGIF]) {            diskData = [self diskImageDataBySearchingAllPathsForKey:key];        }                if (doneBlock) {            doneBlock(image, diskData, SDImageCacheTypeMemory);        }        return nil;    }            NSOperation *operation = [NSOperation new];    dispatch_async(self.ioQueue, ^{                if (operation.isCancelled) {            // do not call the completion if cancelled            return;        }                @autoreleasepool {                                    NSData *diskData = [self diskImageDataBySearchingAllPathsForKey:key];            UIImage *diskImage = [self diskImageForKey:key];            if (diskImage && self.config.shouldCacheImagesInMemory) {                NSUInteger cost = SDCacheCostForImage(diskImage);                                //self.memCache是NSCache创建的一个对象                [self.memCache setObject:diskImage forKey:key cost:cost];            }            if (doneBlock) {                                dispatch_async(dispatch_get_main_queue(), ^{                    doneBlock(diskImage, diskData, SDImageCacheTypeDisk);                });            }        }    });    return operation;}快速查找缓存的方法回调

看完该函数以后在回到上面的看这个快速查找缓存的方法回调

operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) {        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])) {//如果在缓存中找到了image且options选项包含SDWebImageRefreshCached,先在主线程完成一次回调,使用的是缓存中找的图片            if (image && options & SDWebImageRefreshCached) {                dispatch_main_sync_safe(^{                // 如果在缓存中找到了image但是设置了SDWebImageRefreshCached选项,传递缓存的image,同时尝试重新下载它来让NSURLCache有机会接收服务器端的更新                    completedBlock(image, nil, cacheType, YES, url);                });            }            // 如果没有在缓存中找到image 或者设置了需要请求服务器刷新的选项,则仍需要下载            SDWebImageDownloaderOptions downloaderOptions = 0;            //开始各种options的判断            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) {            // 如果image已经被缓存但是设置了需要请求服务器刷新的选项,强制关闭渐进式选项                downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;               // 如果image已经被缓存但是设置了需要请求服务器刷新的选项,忽略从NSURLCache读取的image                downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;            }            //创建下载操作,先使用self.imageDownloader下载            id <SDWebImageOperation> subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) {                __strong __typeof(weakOperation) strongOperation = weakOperation;                if (!strongOperation || strongOperation.isCancelled) {                    // Do nothing if the operation was cancelled                    //如果操作取消了,不做任何事情                    // 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                //如果我们调用completedBlock,这个block会和另外一个completedBlock争夺一个对象,因此这个block被调用后会覆盖新的数据                }                else if (error) {                    //进行完成回调                    dispatch_main_sync_safe(^{                        if (strongOperation && !strongOperation.isCancelled) {                            completedBlock(nil, error, SDImageCacheTypeNone, finished, url);                        }                    });                  //将url添加到失败列表里面                    if (   error.code != NSURLErrorNotConnectedToInternet                        && error.code != NSURLErrorCancelled                        && error.code != NSURLErrorTimedOut                        && error.code != NSURLErrorInternationalRoamingOff                        && error.code != NSURLErrorDataNotAllowed                        && error.code != NSURLErrorCannotFindHost                        && error.code != NSURLErrorCannotConnectToHost) {                        @synchronized (self.failedURLs) {                            [self.failedURLs addObject:url];                        }                    }                }                else {                    //如果设置了下载失败重试,将url从失败列表中去掉                    if ((options & SDWebImageRetryFailed)) {                        @synchronized (self.failedURLs) {                            [self.failedURLs removeObject:url];                        }                    }                    BOOL cacheOnDisk = !(options & SDWebImageCacheMemoryOnly);        //options包含了SDWebImageRefreshCached选项,且缓存中找到了image且没有下载成功                    if (options & SDWebImageRefreshCached && image && !downloadedImage) {                        // Image refresh hit the NSURLCache cache, do not call the completion block // 图片刷新遇到了NSSURLCache中有缓存的状况,不调用完成回调。                }  //图片下载成功并且 设置了需要变形Image的选项且变形的代理方法已经实现                    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), ^{                            //调用代理方法完成图片transform                            UIImage *transformedImage = [self.delegate imageManager:self transformDownloadedImage:downloadedImage withURL:url];                            if (transformedImage && finished) {                                BOOL imageWasTransformed = ![transformedImage isEqual:downloadedImage];                //对已经transform的图片进行缓存                                [self.imageCache storeImage:transformedImage recalculateFromImage:imageWasTransformed imagedata:(imageWasTransformed ? nil : data) forKey:key toDisk:cacheOnDisk];                            }                            //主线程执行完成回调                            dispatch_main_sync_safe(^{                                if (strongOperation && !strongOperation.isCancelled) {                                    completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished, url);                                }                            });                        });                    }//如果没有图片transform的需求并且图片下载完成且图片存在就直接缓存                    else {                        if (downloadedImage && finished) {                            [self.imageCache storeImage:downloadedImage recalculateFromImage:NO imagedata:data forKey:key toDisk:cacheOnDisk];                        }                   //主线程完成回调                         dispatch_main_sync_safe(^{                            if (strongOperation && !strongOperation.isCancelled) {                                completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished, url);                            }                        });                    }                }                if (finished) {       // 从正在进行的操作列表中移除这组合操作                    @synchronized (self.runningOperations) {                        if (strongOperation) {                            [self.runningOperations removeObject:strongOperation];                        }                    }                }            }];          //设置组合操作取消得得回调            operation.cancelBlock = ^{                [subOperation cancel];                @synchronized (self.runningOperations) {                    __strong __typeof(weakOperation) strongOperation = weakOperation;                    if (strongOperation) {                        [self.runningOperations removeObject:strongOperation];                    }                }            };        }//处理其他情况//case1.在缓存中找到图片(代理不允许下载 或者没有设置SDWebImageRefreshCached选项  满足至少一项)        else if (image) {            //完成回调            dispatch_main_sync_safe(^{                __strong __typeof(weakOperation) strongOperation = weakOperation;                if (strongOperation && !strongOperation.isCancelled) {                    completedBlock(image, nil, cacheType, YES, url);                }            });          //从正在进行的操作列表中移除组合操作            @synchronized (self.runningOperations) {                [self.runningOperations removeObject:operation];            }        }          //case2:缓存中没有扎到图片且代理不允许下载        else {        //主线程执行完成回调            dispatch_main_sync_safe(^{                __strong __typeof(weakOperation) strongOperation = weakOperation;                if (strongOperation && !weakOperation.isCancelled) {                    completedBlock(nil, nil, SDImageCacheTypeNone, YES, url);                }            });          //从正在执行的操作列表中移除组合操作            @synchronized (self.runningOperations) {                [self.runningOperations removeObject:operation];            }        }    }];总结一下函数调用1.先调用- (void)sd_setImageWithURL:(nullable NSURL *)url          placeholderImage:(nullable UIImage *)placeholder;2.设置图片- (void)sd_internalSetImageWithURL:(nullable NSURL *)url                  placeholderImage:(nullable UIImage *)placeholder                           options:(SDWebImageOptions)options                      operationKey:(nullable NSString *)operationKey                     setImageBlock:(nullable SDSetImageBlock)setImageBlock                          progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock                         completed:(nullable SDExternalCompletionBlock)completedBlock

2.1 取消该控件对应的之前的所有的下载操作

- (void)sd_cancelImageLoadOperationWithKey:(nullable NSString *)key;

2.2 开始根据图片的url做为key去查找

- (id <SDWebImageOperation>)loadImageWithURL:(nullable NSURL *)url                                     options:(SDWebImageOptions)options                                    progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock                                   completed:(nullable SDInternalCompletionBlock)completedBlock

2.2.1 查找内存和硬盘上的缓存

- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key done:(nullable SDCacheQueryCompletedBlock)doneBlock;

2.3 创建下载队列下载图片

- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url                                                   options:(SDWebImageDownloaderOptions)options                                                  progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock                                                 completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;

2.4 最后将进行的操作,放到view对应的opationsDicaionary的字典中。记录当前的操作队列

- (void)sd_setImageLoadOperation:(nullable id)operation forKey:(nullable NSString *)key

“ios开发中SDWebImage方法怎么用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注花开半夏网站,小编将为大家输出更多高质量的实用文章!

君子莲(www.junzilian.com)湖南省长沙、株洲、湘潭城市宣传信息网,提供房产,人才招聘,家居装饰,教育,论坛,旅游,特产,美食,天气,娱乐,企业等资讯。



最新餐饮知识

热门推荐

为你推荐