SDWebImage 引发的 cell不断下拉引起的闪退 卡顿

最近在我们的项目中出现了一个问题,暴力测试 高速上拉cell 不断加载出更多的cell  就会出现app 闪退。调试的时候 会发现 高速拉出很多cell的时候 内存 会有极大的浮动,拉出差不多200多个cell的时候就会出现闪退。为了弄清楚是怎么回事,我查了很多资料 ,也看了很多国外的博客 ,后来终于让我发现了问题所在,废话不多说 ,听我细细道来

1.首先是SDwebimage的原理:



UIImageView+WebCache:setImageWithURL:placeholderImage:options:先显示 placeholderImage ,同时由SDWebImageManager 根据 URL 来在本地查找图片。

SDWebImageManager:downloadWithURL:delegate:options:userInfo:SDWebImageManager是将UIImageView+WebCache同SDImageCache链接起来的类, SDImageCache:queryDiskCacheForKey:delegate:userInfo:用来从缓存根据CacheKey查找图片是否已经在缓存中

如果内存中已经有图片缓存, SDWebImageManager会回调SDImageCacheDelegate :imageCache:didFindImage:forKey:userInfo:

而 UIImageView+WebCache 则回调SDWebImageManagerDelegate:webImageManager:didFinishWithImage:来显示图片。

如果内存中没有图片缓存,那么生成 NSInvocationOperation 添加到队列,从硬盘查找图片是否已被下载缓存。

根据 URLKey 在硬盘缓存目录下尝试读取图片文件。这一步是在 NSOperation 进行的操作,所以回主线程进行结果回调notifyDelegate:。

如果上一操作从硬盘读取到了图片,将图片添加到内存缓存中(如果空闲内存过小,会先清空内存缓存)。SDImageCacheDelegate 回调imageCache:didFindImage:forKey:userInfo:。进而回调展示图片。

如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片,回调imageCache:didNotFindImageForKey:userInfo:。

共享或重新生成一个下载器SDWebImageDownloader开始下载图片。

图片下载由 NSURLConnection 来做,实现相关 delegate 来判断图片下载中、下载完成和下载失败。

connection:didReceiveData:中利用 ImageIO 做了按图片下载进度加载效果。

connectionDidFinishLoading:数据下载完成后交给SDWebImageDecoder做图片解码处理。

图片解码处理在一个 NSOperationQueue 完成,不会拖慢主线程 UI。如果有需要对下载的图片进行二次处理,最好也在这里完成,效率会好很多。

在主线程notifyDelegateOnMainThreadWithInfo:宣告解码完成,imageDecoder:didFinishDecodingImage:userInfo:回调给 SDWebImageDownloader。

imageDownloader:didFinishWithImage:回调给 SDWebImageManager 告知图片下载完成。

通知所有的 downloadDelegates 下载完成,回调给需要的地方展示图片。

将图片保存到 SDImageCache 中,内存缓存和硬盘缓存同时保存。

写文件到硬盘在单独 NSInvocationOperation 中完成,避免拖慢主线程。

如果是在iOS上运行,SDImageCache 在初始化的时候会注册notification

到 UIApplicationDidReceiveMemoryWarningNotification 以及

UIApplicationWillTerminateNotification,在内存警告的时候清理内存图片缓存,应用结束的时候清理过期图片。

SDWebImagePrefetcher可以预先下载图片,方便后续使用。更详细的可以 转

http://www.open-open.com/lib/view/open1409822188744.html 




2.整个过程都看似非常的完美,内存处理的也非常好,为什么还会出现问题呢,问题所在的地方就

这个方法是下载图片之后 做的一些处理

是对下载的图片进行重绘,从而带到压缩的作用,这个方法很好 大大的减少了因为图片太大而引起的内存暴增,但是问题也来了,大量下拉cell 不断调用

从而不断的调用这个压缩的方法  就会导致内存 极具增大  但 sd 自带的释放内存的方法  缺不能触发 ,导致app 闪退



3.解决办法就是

这个属性 ,关闭这个属性就可以了    


这个属性是控制其是否压缩的   关闭这个属性即可 



关闭这个属性就可以了,但是 也会带来 内存 增高的 问题  ,只是这样带来的内存增高是可以让VC捕捉到的  ,这个 内存 是因为缓存了 大量的图片引起的 

所以在收到内存警告的时候清除缓存就可以了 。好了  至此这 问题就解决了。

分享我的经验希望能帮到大家 如有不对之处 请大家多多指教。 联系qq 719967870

你可能感兴趣的:(SDWebImage 引发的 cell不断下拉引起的闪退 卡顿)