很多公司会有这种需求,要求在cell中下载文件,或者显示下载进度。由于cell的复用机制导致在滑动的时候,下载进度出现紊乱的效果,这种问题出现最好的解决方式是:
* 在下载的时候,下载的过程不要在cell里面进行
* 下载过程最好在后台线程进行,在后台开辟多条线程,可以采用NsOperation的方式,能够控制下载的暂停与开始
* 下载的结果和数据模型进行绑定,根据数据模型实时刷新cell的数据,因为cell会复用,数据模型不会复用,cell和数据模型绑定
处理好各个层级的关系,数据层和UI层的分层关系,就能很好地解决这个问题。最后别忘了刷新UI的时候要回到主线程。
当时今天只讨论这个问题,显得这个问题过于简单。今天我们讨论另一层层面的问题,结合block,结合cell复用,一起来探索。
[[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL
URLWithString: imageUrl] options:SDWebImageDownloaderUseNSURLCache
progress:NULL completed:^(UIImage *image, NSData *data, NSError *error, BOOL
finished) { dispatch_async(dispatch_get_main_queue(), ^{ __strong
__typeof(&*weakSelf)strongSelf = weakSelf; [strongSelf showImageView:imageUrl
image: image]; }); }];
如上代码,如果整个下载过程发生在cell里面,就会发生cell复用混乱的问题,而且问题根本不好查,也不好修改。
问题的原因是,虽然这个cell会绑定model,下载过程也是model的url,但是过程中,self.model.imageUrl被局部变量imageUrl来接收,局部变量又在block里面进行了展示,所以下载完的结果不一定展示到了当前的cell中。很多小伙伴可能纳闷,cell依赖于model,局部变量的值依赖于model,没毛病呀,数据不会发生问题呀。
可问题偏偏还是发生了!!!
经过长时间的推敲和修改代码,发现把代码改成如下就不会有问题:
[strongSelf showImageView:self.model.imageUrl image: image];
问题原因是:局部变量imageUrl依赖于block,block又在cell里面,局部变量会随着cell复用而跟随到复用的cell,所以展示的cell的url就会发生问题。
标记:
* 直接用UIImageView的sd方法下载网络图片不会有问题,因为方法内部做了处理
* 所以最根本的解决思路就是,压根就不应该在cell里面下载图片,而是应该在子线程下载,然后下载过程依赖于model。
热门工具 换一换