利用SDWebImage将imageStr数组转成image数组

代码

//封装
+ (void)fetchCacheImgs:(NSArray *)arrImgStr finishBlk:(void(^)(NSArray *arrImgs))finishBlk{
    NSMutableArray *arrMTemp = [NSMutableArray arrayWithArray:arrImgStr];
    __block NSInteger sum = 0;
    [arrImgStr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSString *strImg = obj;
        [[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:strImg] options:0 progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
            sum++;
            [arrMTemp replaceObjectAtIndex:idx withObject:image];
            if (sum == arrImgStr.count) {
                //结束
                if (finishBlk) {
                    finishBlk(arrMTemp);
                }
            }
        }];
    }];
}

//调用
[UIImage fetchCacheImgs:@[
                              @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1558086203027&di=e27944d7d427004a71c2cdb0fbf58125&imgtype=0&src=http%3A%2F%2Fpic139.nipic.com%2Ffile%2F20170819%2F19317778_203257969000_2.jpg",
                              @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1558086203027&di=83035960a9ac35ee59c90d277e29b484&imgtype=0&src=http%3A%2F%2Fs1.sinaimg.cn%2Fmw690%2F0021szcogy6VoIyTEw8d0%26690",
                              @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1558086203027&di=5e307af14e64026034b3bf77ac423c21&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2Fbf389549d64d6853870dbda4e811a0f56ca138aaa424-lj2LaA_fw658",
                              @"https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1792894298,856132472&fm=26&gp=0.jpg"
                              ] finishBlk:^(NSArray *arrImgs) {
                                  self.vm.arrMImgCountImg = [NSMutableArray arrayWithArray:arrImgs];
                              }];

问题

在这里插入图片描述

答案

其实这个和block的机制有关系。block访问外部变量有两种方式。

一种是值传递,另外一种是址传递。
将变量前面加了__block修饰符后就变成了址传递。这时候block内部和外部共享一个变量地址所以可以修改外部变量的值。

还有一种是值传递。就是block会将外部变量的值传递进入block内部,最终用结构体来保存这个值。

让我们来分析下以上代码
首先外部数组遍历,idx=0这时候block将0传入内部利用结构体保存。然后开多线程,再之后idx=1这时候把1传入block内部用结构体保存起来再开一条线程。最终数组遍历完毕,开了多条线程。这时候图片有的数据比较大,有的数据量比较小。所以虽然先开的线程却不一定先请求完数据。所以这里涉及到了多线程排序问题。

比如第二次开的线程图片数据比较小,先请求完毕,先进入block这时候之前传入的idx的值1就起到了作用,block会在内部结构体里去取idx,取的值就是上次传入的值也就是1。我们利用可变数组的特性将对应的字串图片替换成真正的图片即可。

证明

我们改写成for循环,循环变量前边用__block来修饰。让它变成址传递,我们再试试看,会发现结果变了。


在这里插入图片描述

我们可以尝试去掉__block修饰符再次运行。


在这里插入图片描述

这也从一方面证明了block的特性,值传递,址传递。

另一方面呢可以查看cpp文件,通过查看代码的方式也可以说明这点。

总结

其实以上代码主要是利用SDWebImage的函数loadImageWithURL来完成图片字串转成图片数据。这里会先去缓存区找,找到后直接返回,找不到才去下载。

有点跑题了,从利用SDWebImage完成strImg转Image变成了讲述block的特性。不过我觉得这个地方是值得我们注意的。也是一个容易忽视的知识点。

今天想讲述的主要是block的用法。我们利用了block访问外部变量值的特性来完成了"线程排序"。

你可能感兴趣的:(利用SDWebImage将imageStr数组转成image数组)