首页 > 随笔档案 > iOS开发-你真的会用SDWebImage?(转发)

iOS开发-你真的会用SDWebImage?(转发)

Publish:

原文地址: http://www.jianshu.com/p/dabc0c6d083e

 

SDWebImage作为目前最受欢迎的图片下载第三方框架,使用率很高。但是你真的会用吗?本文接下来将通过例子分析如何合理使用SDWebImage。

使用场景:自定义的UITableViewCell上有图片需要显示,要求网络网络状态为WiFi时,显示图片高清图;网络状态为蜂窝移动网络时,显示图片缩略图。如下图样例:

图中显示的图片符合根据网络状态下载要求

// AppDelegate.m 文件中

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

{

    // 监控网络状态

    [[AFNetworkReachabilityManager sharedManager] startMonitoring];

}

// 以下代码在需要监听网络状态的方法中使用

AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];

    if (mgr.isReachableViaWiFi)     { // 在使用Wifi, 下载原图

    } else     { // 其他,下载小图

    }

 }

// 利用MVC,在设置cell的模型属性时候,下载图片

- setItem:(CustomItem *)item

{

    _item = item;

    UIImage *placeholder = [UIImage imageNamed:@”placeholderImage”];

    AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];

    if (mgr.isReachableViaWiFi) { // 在使用Wifi, 下载原图

        [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder];

    } else { // 其他,下载小图

        [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.thumbnailImage] placeholderImage:placeholder];

    }

}

- setItem:(CustomItem *)item

{

    _item = item;

    if (缓存中有原图) 

    {

        self.imageView.image = 原图;

    } else 

    {

        if (Wifi环境) 

        {

            下载显示原图

        } else if (手机自带网络) 

        {

            if (3G\4G环境下仍然下载原图) 

            {

                下载显示原图

            } else 

            {

                下载显示小图

            }

        } else 

        {

            if (缓存中有小图) 

            {

                self.imageView.image = 小图;

            } else  // 处理离线状态

            {

                self.imageView.image = 占位图片;

            }

        }

    }

}

- setItem:(CustomItem *)item

{

    _item = item;

     // 占位图片

    UIImage *placeholder = [UIImage imageNamed:@”placeholderImage”];

    // 从内存\沙盒缓存中获得原图,

    UIImage *originalImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.originalImage];

    if (originalImage) { // 如果内存\沙盒缓存有原图,那么就直接显示原图(不管现在是什么网络状态)

        self.imageView.image = originalImage;

    } else { // 内存\沙盒缓存没有原图

        AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];

        if (mgr.isReachableViaWiFi) { // 在使用Wifi, 下载原图

            [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder];

        } else if (mgr.isReachableViaWWAN) { // 在使用手机自带网络

            //     用户的配置项假设利用NSUserDefaults存储到了沙盒中

            //    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@”alwaysDownloadOriginalImage”];

            //    [[NSUserDefaults standardUserDefaults] synchronize];

#warning 从沙盒中读取用户的配置项:在3G\4G环境是否仍然下载原图

            BOOL alwaysDownloadOriginalImage = [[NSUserDefaults standardUserDefaults] boolForKey:@”alwaysDownloadOriginalImage”];

            if (alwaysDownloadOriginalImage) { // 下载原图

                [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder];

            } else { // 下载小图

                [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.thumbnailImage] placeholderImage:placeholder];

            }

        } else { // 没有网络

            UIImage *thumbnailImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.thumbnailImage];

            if (thumbnailImage) { // 内存\沙盒缓存中有小图

                self.imageView.image = thumbnailImage;

            } else { // 处理离线状态,而且有没有缓存时的情况

                self.imageView.image = placeholder;

            }

        }

    }

}

解决了吗?真正的坑才刚刚开始。

cell还没有被推入缓存池

那么该如何解决这个棘手的问题呢?

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {

    // 关闭当前图片的下载操作

    [self sd_cancelCurrentImageLoad];

    objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    if (!(options & SDWebImageDelayPlaceholder)) {

        dispatch_main_async_safe(^{

            self.image = placeholder;

        });

    }

    if (url) {

        // check if activityView is enabled or not

        if ([self showActivityIndicatorView]) {

            [self addActivityIndicator];

        }

        __weak __typeof(self)wself = self;

        id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {

            [wself removeActivityIndicator];

            if (!wself) return;

            dispatch_main_sync_safe(^{

                if (!wself) return;

                if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)

                {

                    completedBlock(image, error, cacheType, url);

                    return;

                }

                else if (image) {

                    wself.image = image;

                    [wself setNeedsLayout];

                } else {

                    if ((options & SDWebImageDelayPlaceholder)) {

                        wself.image = placeholder;

                        [wself setNeedsLayout];

                    }

                }

                if (completedBlock && finished) {

                    completedBlock(image, error, cacheType, url);

                }

            });

        }];

        [self sd_setImageLoadOperation:operation forKey:@”UIImageViewImageLoad”];

    } else {

        dispatch_main_async_safe(^{

            [self removeActivityIndicator];

            if (completedBlock) {

                NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @”Trying to load a nil url”}];

                completedBlock(nil, error, SDImageCacheTypeNone, url);

            }

        });

    }

}

我们惊奇的发现,原来SDWebImage在下载图片时,第一件事就是关闭imageView当前的下载操作!

- setItem:(CustomItem *)item

{

    _item = item;

  // 占位图片

    UIImage *placeholder = [UIImage imageNamed:@”placeholderImage”];

    // 从内存\沙盒缓存中获得原图

    UIImage *originalImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.originalImage];

    if (originalImage) { // 如果内存\沙盒缓存有原图,那么就直接显示原图(不管现在是什么网络状态)

        [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder];

    } else { // 内存\沙盒缓存没有原图

        AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];

        if (mgr.isReachableViaWiFi) { // 在使用Wifi, 下载原图

            [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder];

        } else if (mgr.isReachableViaWWAN) { // 在使用手机自带网络

            //     用户的配置项假设利用NSUserDefaults存储到了沙盒中

            //    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@”alwaysDownloadOriginalImage”];

            //    [[NSUserDefaults standardUserDefaults] synchronize];

#warning 从沙盒中读取用户的配置项:在3G\4G环境是否仍然下载原图

            BOOL alwaysDownloadOriginalImage = [[NSUserDefaults standardUserDefaults] boolForKey:@”alwaysDownloadOriginalImage”];

            if (alwaysDownloadOriginalImage) { // 下载原图

                [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder];

            } else { // 下载小图

                [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.thumbnailImage] placeholderImage:placeholder];

            }

        } else { // 没有网络

            UIImage *thumbnailImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.thumbnailImage];

            if (thumbnailImage) { // 内存\沙盒缓存中有小图

                [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.thumbnailImage] placeholderImage:placeholder];

            } else {

                [self.imageView sd_setImageWithURL:nil placeholderImage:placeholder];

            }

        }

    }

}

 

文/hosea_zhou(简书作者)

原文链接:http://www.jianshu.com/p/dabc0c6d083e

著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

声明: 本文采用 BY-NC-SA 授权。转载请注明转自: levy