在加载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进行加载的时候,我们一次发出大量下载请求,实际上其中有很多是我们暂时不需要加载的,所有这又涉及到一个下载请求的手动管理。各位看官可自行实验。
感谢各位看官,有不足不对的地方劳请指出,有更好的方法也可以多多交流。