【IOS】解决sd_webimage 下载网络图片 cell展示不全的三种方法。

在加载UIcollection或者UItableView的cell时使用sd_webimage加载图片,例如这样:

ColCardCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellid" forIndexPath:indexPath];
        cell.backgroundColor = [UIColor lightGrayColor];
 ColModelItem *item1 = [[ColModelItem alloc]init];
item1 setTitle:((ThemeList *)dataArr[indexPath.section-1]).name];
        NSString *url = [NSString stringWithString:((ThemeList *)dataArr[indexPath.section-1]).themepic_url];
        url = [url stringByReplacingOccurrencesOfString:@"\r\n" withString:@""]; //删除网络请求下来的url末尾自带的换行符
        [temp sd_setImageWithURL:[NSURL URLWithString:url] placeholderImage:nil options:SDWebImageRetryFailed];
        [item1 setImg:temp];
        [cell setItem:item1];    //通过item向cell加载数据
        return cell;

会出现view的cell上的图片只展示了第一张或者最后一张,其他的图片需要滑动刷新或者退出重进才能正常展示的问题。

出现这个问题的原因是因为界面一次请求多个cell的下载请求后,这个API的请求会取消掉之前产生图片下载请求任务,除了第一个cell其余传给cell的只是占位图,其余cell需要刷新进行再次请求才能将图片正常展示。

解决方法亲测有三种。

一.使用completedBlock, 图片加载完成后对cell进行赋值。

[tempView sd_setImageWithURL:[NSURL URLWithString:str] placeholderImage:nil options:SDWebImageRetryFailed completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

dispatch_async(dispatch_get_main_queue(), ^{

cell.img = tempView.image;

});

}];

但是需要注意的是,tempView如果是函数内定义的局部变量,本身是不持有对象的,进入Block前就被释放掉了,所以无法对cell进行赋值。

解决方法可以将tempView声明为强引用的全局变量,也可以通过[self.imgViewArr addObject:tempView],将tempView强引用并赋予指针,completedBlock便能够生效了。注意ui的刷新在主线程中进行。

二.自定义cell的set方法

第二种方法可以通过将sd_webimage的下载方法移步到cell的set方法中进行,也就是在加载cell时,只将图片的url做为参数正常传给cell,sdwebimage的url解析和下载数据的工作放在cell.m文件里完成,这样的话每个 cell单独完成数据加载工作只发送一次请求任务,sdwebimage将正常工作,那么所有的cell也就能正常展示了。

如下:

@implementation Cell{
    UIImageView *_imageView;
}

-(void)setImage:(Nsstring *)iamgeurl {
 
        NSString * url = imageurl;
        url = [url stringByReplacingOccurrencesOfString:@"\r\n" withString:@""];
        [_imageView sd_setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"图片"] options:SDWebImageAllowInvalidSSLCertificates];
    
}

 

三.使用downloadImageWithURL方法进行数据下载。

前面说到sd_setImageWithURL会取消掉多余的请求任务,那么downloadImageWithURL方法不会取消掉之前产生的请求任务。

在downloadImageWithURL中请求可以正常回调completedBlock,展示出我们的图片。

但是使用这个方法也有两个弊端,一是downloadImageWithURL只能完成单纯的下载操作,并没有任何的缓存机制,如果需要缓存图片的话,需要自己写缓存方法十分不便,二是当有大量cell进行加载的时候,我们一次发出大量下载请求,实际上其中有很多是我们暂时不需要加载的,所有这又涉及到一个下载请求的手动管理。各位看官可自行实验。

 

感谢各位看官,有不足不对的地方劳请指出,有更好的方法也可以多多交流。

 

你可能感兴趣的:(IOS入门,Sdwebimage)