前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SDWebImage 引发的 cell不断下拉引起的闪退 卡顿

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

作者头像
陈雨尘
发布2018-06-01 17:11:02
1.3K0
发布2018-06-01 17:11:02
举报
文章被收录于专栏:雨尘分享

最近在我们的项目中出现了一个问题,暴力测试 高速上拉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捕捉到的  ,这个 内存 是因为缓存了 大量的图片引起的 

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016.06.01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档