<dl id='ee03'></dl>

    <code id='ee03'><strong id='ee03'></strong></code>
    <span id='ee03'></span>

    <fieldset id='ee03'></fieldset>

    <acronym id='ee03'><em id='ee03'></em><td id='ee03'><div id='ee03'></div></td></acronym><address id='ee03'><big id='ee03'><big id='ee03'></big><legend id='ee03'></legend></big></address>

    <ins id='ee03'></ins>
    <i id='ee03'><div id='ee03'><ins id='ee03'></ins></div></i>

      <i id='ee03'></i>

          1. <tr id='ee03'><strong id='ee03'></strong><small id='ee03'></small><button id='ee03'></button><li id='ee03'><noscript id='ee03'><big id='ee03'></big><dt id='ee03'></dt></noscript></li></tr><ol id='ee03'><table id='ee03'><blockquote id='ee03'><tbody id='ee03'></tbody></blockquote></table></ol><u id='ee03'></u><kbd id='ee03'><kbd id='ee03'></kbd></kbd>
          2. iOS优化(三)没错我还是滑动优化

            • 时间:
            • 浏览:15
            • 来源:124软件资讯网

            近期把滑动优化的一些履历整理了一下  ,在公司做了一次手艺分享  ,和我之前的文章有一小部门重叠  。现摘要如下  ,希望各人不惜见教  ,配合讨论前进 。

            一.滑动优化的玄学

            为什么说是玄学呢  ,由于大部门情形下的APP  ,用不到这些优化的点 ,过早的优化是恶魔  ,认真正泛起性能问题的时间  ,再思量这些方面的优化  。

            1.多个透明元素重叠显示的性能问题  。

            • 解决方案:合并成一张图显示

            • 原理:CPU方面  ,淘汰了UIKit的建立消耗  ,GPU方面  ,制止了合成渲染发生的消耗 。

            • AsyncDisplayKit(现在叫Texture)  ,针对多个透明元素的重叠  ,预合并无点击响应  ,不改变更画的图层 。

            • Texture的保持流通的原理:UIKit不是线程宁静的 ,以是必须在主线程改动 。Texture使用中心变量存储改动  ,保证线程宁静  ,在合适的时机将并发操作同步到主线程  。

            • 暂时不用Texture的缘故原由:需要用Texture Node Container替换UIKit元素  ,成本较大  。

            2.静态cell、多图待加载的优化

            • 解决方案:合并成一张图显示;

            • 原理:提升I/O速率 ,一个大文件的读取速率  ,通常比多个小文件要快 。

            3.展示适合界面尺寸图片  ,不举行拉伸缩放 。

            • 解决方案:从服务器拉取合适尺寸的图片(例如七牛的服务就带裁剪/压缩参数);

            • 原理:过大图片对内存消耗庞大(图片占用内存 = 图像高×图像宽×像素位数);不切合UIImageView尺寸的图片  ,举行重新缩减/放大尺寸的消耗是很是庞大的  。

            4.imageNamed和imageWithContentsOfFile

            这个知道的人比力多 ,由于缓存图片的消耗通常是肉眼可见的多  。
            常用的元素例如icon之类的  ,接纳imageNamed:  ,系统会有缓存  。
            若是是较大或者不常用的图片资源  ,接纳imageWithContentsOfFile:  。

            5.淘汰autolayout的使用

            • 解决方案:页面元素多的时间 ,淘汰autolayout结构 ,接纳frame  。

            • 原理:元素多时  ,autolayout的消耗很是惊人(http://pilky.me/36/) ,之前看过搜狗的iOS分享 ,搜狗输入法键盘弹出狂卡即是此缘故原由;

            6.获取文件巨细

            • 解决方案:不要使用NSFileManager ,用C的stat来获取文件信息  。

            • 实例:获取一个目录下所有文件巨细 ,举行多次递归盘算 ,stat险些瞬间完成 ,NSFileManager耗时较长 。

            7.NSDateFormatter发生较大消耗

            • 解决方案:.缓存NSDateFormatter效果 ,不多次建立  ,实时释放  。

            • 做过类似日历的同砚应该都懂


            8.图片解码:

            • 解决方案:CALayer 被提交到 GPU 前  ,CGImage 中的数据才会获得解码 ,GPU执行  ,卡主线程 。常见的做法是在后台线程先把图片绘制到 CGBitmapContext 中 ,然后从 Bitmap 直接建立图片  。

            • SDWebImage/YYImage等图片库都是这么做的  ,有兴趣的同砚可以去看下源码 。若是你是自己做图片下载 ,就要思量到相关优化  。

            二.cell高度预盘算/缓存

            • 一样平常情形下 ,不要用estimatedRowHeight ,否则容易鬼畜;

            • systemLayoutSizeFittingSize:这个要领 ,就是大部门cell结构库接纳的要领  ,只要从上至下结构所有生效 ,就能盘算高度 ,不要多次挪用;

            • 由于UITableView绘制历程中多次挪用绘制 ,以是缓存高度盘算效果  ,可以有用的增添滑动流通度;

            • 当cell高度改变 ,记得实时替换缓存;

            三.离屏渲染

            触发条件:CALayer 的 border、圆角、阴影、遮罩(mask)  ,CASharpLayer 的矢量图形显示 。
            主要问题:GPU占满  ,CPU空闲
            解决要领:
            1.开启CALayer.shouldRasterize  ,转嫁到CPU上;
            2.粗暴绘图/截图实现border和圆角;
            3.砍死设计师  。

            最近拖延症有点厉害  ,这篇文章想写了良久都没写出来  ,我先摘要一部门思绪出来  。

            拖延症晚期患者.png

            曾经的需求是这样的:

            注重需求的圈和头像之间是有清闲的.png

            初期方案是图片下载完成后  ,裁成圆形  ,然后外面用贝塞尔画一个圈  ,凭据差别的UI缓存差别多个带圈儿的图;
            然而...神奇的产物第二版给我整出了无数个种种差别巨细、间距、透明度的圈 。这样就意味着我得缓存无数带着各色圈儿的图 。

            厥后突然灵光一闪  ,单独设layer的圆角貌似不引发离屏渲染(有说法是iOS8之后) 。以是厥后方案酿成  ,UIView嵌套一个UIImageView  ,只缓存裁剪过的图片  。

            可是这样的话  ,实在UIKit的建立要比读取画好的图更耗性能 。以是这是个最终的问题  ,时间/空间  ,事实选哪个  。

            四.图片的处置惩罚

            1.SDWebImage的外层干了啥


            这篇文章写了1/4的样子 ,详细的会在这篇文章里 ,十分心疼自己  。下面简朴说说SDWebImage的外层都干了啥:

            • 重用cell的时间 ,cancel之前下载operation;

            • 二级缓存:memory/disk;

            • 合并回调  ,多次挪用只回调一次;

            2.项目中现实遇到的问题

            我们做了个类似SDWebImage的工具 ,来实现神奇的需求 ,历程中遇到了一些问题:

            • 从disk读取需要时间  ,在memory没有的情形下  ,导致image = nil的一瞬间闪动:我把SDWeb的demo改了改 ,左边按钮ReloadData  ,右边按钮扫除内存(memory)缓存  ,在reload的一瞬间  ,展示了placeHolder的图  。


            • UICollectionView, reloadData 迷之移位闪耀问题:当reloadData的时间 ,重用的cell神奇的变换了序次 ,此时memory里只要一图片不存在  ,就会有一瞬间的闪动  。

            • 上面两个问题的解决要领有:

              • 只管制止reloadData  ,可以找到visibleCells  ,逐一替换换图片;

              • 优化细节  ,在发现disk内里有图的时间  ,image不设为nil  ,制止闪动;

              • 保证memory缓存的巨细和数目  ,能知足界面需求;

            • 请求没有合并/回调没有合并;
              这个比力好解决 ,就是请求之前判断该请求是否在执行  ,若在执行  ,则将回调暂存到该请求下  ,等完成后一并挪用  。

            五.ScrollView滑动优化

            1.滑动时的署理

            • scrollViewDidScroll:现实上就是contentOffset的KVO

            • scrollViewWillBeginDragging:

            • scrollViewWillEndDragging: withVelocity: (points/millisecond这现实上是个速率的参数)targetContentOffset:(这是一个可以传值的指针  ,可以控制最后的减速动画)

            • scrollViewDidEndDragging: willDecelerate:(拖动竣事 ,若是仍有速率  ,会执行后面两个要领)

            • scrollViewWillBeginDecelerating:

            • scrollViewDidEndDecelerating:

            • 需要注重scrollView的dragging属性在decelerate的历程中仍然为YES

            2.特殊情形

            drag完 ,正decelerating时(didEndDecelerating尚未挪用) ,强行再次drag(单指制止滑动  ,双指连环滑)

            • 单指制止滑动:没有decelerate ,willBeginDecelerating不会被挪用  ,但前一次留下的 didEndDecelerating 会被挪用(后面会联合VVWeibo的例子讲述这里怎么处置惩罚)

            • 双指连环滑动:willBeginDecelerating会先于didEndDecelerating挪用 ,就是说这种情形didEndDecelerating会在你手指脱离屏幕且屏幕制止的情形下挪用  。

            3.VVWeibo的做法

            • scrollViewWillEndDragging: withVelocity: targetContentOffset:时  ,可以从targetContentOffset判断即将加载的那一页cell  ,从而预先加载  ,UITableView有传入rect返回cells的要领  ,UICollectionView得强行取两个点获得这两个点cell的IndexPath  ,然后获得cells  。

            • 遇到前文单指制止的处置惩罚  ,VVWeibo是在UITableView的子类捕捉了touchEvent ,然后reloadData  ,我就没有做子类了  。最后做了一系列神奇的判断  ,然后reload  。可是仍然遇到了 reloadData 迷之移位闪耀问题;厥后我加入了速率的判断  ,这个已经不会触发了  ,我就暂时注销掉了  ,等候下一步优化  。

            4.最迷的问题

            UICollectionViewLayout的prepareLayout挪用了过多次数 ,是由于shouldInvalidateLayoutForBoundsChange:这个要领灾难的挪用了多次  ,newBounds的x和y现实上随着滑动一直在变 ,return YES的话就一直重新结构  ,最后用magicNumber存他的size  ,当size转变才返回YES ,就很强行的解决了 。

            六.妖怪般的视频播放

            这里涉及营业逻辑过多  ,我也不利便多写  ,就写一些历程中遇到的问题:

            • scrollViewDidEndDecelerating的VisibleItems为nil  。换个线程/延时去取 ,就能取到  。

            • 缩小播放区域 ,跟前面的取点找目的cell的操作类似  ,找出首尾点 ,中心的cell  ,即是需要播放的cell  。

            • 多个等候播放的AVPlayerItemVideoOutput ,会导致一部门失效  ,内存越小的机子上越显着  。
              解决要领:播放前再把url赋给playerItem  ,一定水平制止过多playerItem失败的问题;

            • 收支页面找到所有playerItem并干掉  ,制止影响其他播放;

            • GLKView的reuse在狂滑的时间十分耗内存  ,而不reuse的话  ,重用的时间 ,会显示上一个页面的残影  ,解决要领是先用图片盖住残影 ,在播前  ,清算上一次播放的残余;

            • 加入一个Timer  ,通过记载偏移量来控制滑动速率  ,高速率的时间  ,不绘制/下载图片  。这样也解决了双指狂滑的时间  ,无法很好的判断当前是否绘制的问题 。

            Conference

            http://wereadteam.github.io/2016/05/03/WeRead-Performance/  微信念书 iOS 性能优化总结
            http://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/  iOS 保持界面流通的技巧
            http://blog.sunnyxx.com/2015/05/17/cell-height-calculation/ 优化UITableViewCell高度盘算的那些事
            http://tech.glowing.com/cn/practice-in-uiscrollview/ UIScrollView 实践履历
            《High Performance iOS Apps》这本真是神书 ,有兴趣深入学习优化的可以去看看 ,中文的貌似有美团手艺团队翻译的