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捕捉到的  ,这个 内存 是因为缓存了 大量的图片引起的 

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏有困难要上,没有困难创造困难也要上!

iOS提交Appstore时报错: iTunes Store operation failed.

37812
来自专栏葡萄城控件技术团队

Webpack4干货分享:第一部分,入口、输入和ES6模块

转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。

1042
来自专栏自动化测试实战

《selenium2 python 自动化测试实战》(13)——上传文件

3876
来自专栏zaking's

走进webpack(2)--第三方框架(类库)的引入及抽离

  正文之前,由于这是一个系列的文章,可能第一次看到的看官老爷们会觉得突兀,如果你是webpack新手,我建议你先从前几篇文章看起,如果你对webpack有一些...

45011
来自专栏向治洪

React Native项目组织结构介绍

代码组织: 目录结构: . ├── components //组成应用的各个组件 │   ├── Routers.android.js //每个组...

2827
来自专栏smy

微信小程序避坑指南

 详见官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/client-lib/cl...

5133
来自专栏极客编程

Vue.js如何写一个简单的原生js模块,浏览器中的表现如何?

浏览器正在逐步的支持原生JavaScript模块。Safari和Chrome的最新版本已经支持它们了,Firefox和Edge也将很快推出。

2132
来自专栏阮一峰的网络日志

短网址还原的Bookmarklet

如今,很多网站提供短网址服务。 ? 但是有时候,我们需要知道真实网址是什么。 ? 一个个点击,实在太麻烦。何况在国内,很多网址是点不开的。 我一直希望,有人做一...

3698
来自专栏王大锤

升级xcode7.0 第三方库不能用的解决方法(bitcode是什么鬼?)

3037
来自专栏Puppeteer学习

一步一步学习Vue(十)

2394

扫码关注云+社区

领取腾讯云代金券