原文链接:http://www.jianshu.com/p/f4adce56166f

不忘初心

在过去几年间,移动应用以雷霆之势席卷全球。我们在工作和休闲时间中使用互联网的方式,已经随着移动应用的前进脚步发生了变革。在开发应用的时候,人们也开始考虑“移动优先”的做法。我们正在面对全新一代的移动设备,诸如可穿戴设备或众多移动配件——正是它们构成了“万物互联”的世界。我们将面对全新的用户界面,通过它们数据展示及指令接收处理。同时,我们还将看到,越来越多的公司将真正地践行“移动优先”的思路。而在未来数年中,这一切都将影响我们设计、开发和测试软件的方式。

把一个客户端做得稳定、无奔溃、流畅,是写客户端朋友的梦想,但是,我们面临的结果往往是不如人意的。天下武功,唯快不破。很多公司都信奉这个教条。恨不得把app开发周期压缩到最低,这就导致了开发中隐藏了很多问题。有点经验的工程师草率的优化一下,更糟的情况是那些没有经验的工程师甚至不会对app进行任何优化,这将会使情况变的更糟。

十年前,移动设备的硬件资源是非常有限的.甚至连浮点数都是被禁止的.因为浮点数能导致计算的速度变慢。科技发展如此迅速的今天,硬件很大程度上可以弥补软件的短板。但是硬件的进步终究无法掩饰软件的不足,这也是写这篇文章的初心。

移动端关注要点

在程序开发中,测试是必不可少的。移动端测试按大的类型划分可以分为白盒测试和黑盒测试。

白盒测试一般是由开发人员使用编码的方式进行。测试者需要接触程序的内部代码;而黑盒测试可以在不知道程序内部结构和代码的情况下进行。

下面是主要的测试流程了:
冒烟测试:在软件测试中,冒烟测试是指快速验证APP的主要功能(例如:微信的登陆、退出、发消息等功能) 。如果没有发现问题,再进行更加深入的测试工作;如果发现有问题,就说明APP有重大缺陷。

功能测试:功能测试也叫行为测试,需要根据测试用例来验证应用预期的功能有没有实现。

自由探索式测试:尝试边界条件、输入特殊符号、异常网络环境、突然中断程序等操作 。功能测试的目的是验证正常的功能有没有实现,而自由探索测试的目的就是为了试试应用在极端的操作下会不会出现问题。探索式测试就是要找到能让应用出错的操作。

回归测试:对之前使用我们的服务测试过的应用,将案例复测一遍。

移动端关注的一些指标
运行多少小时不崩溃;
多次打开页面,控制崩溃率;
界面优化,如何才能让用户不急躁、不烦躁;
服务器没有返回数据,是否会导致奔溃;
网络不好,数据来的太慢,界面是否不流畅;
从数据库读的数据太慢如何解决等。

移动端界面应该有自己的逻辑,需要网络数据的地方,应该有默认值,这样在网络数据没有返回的情况下,让用户有数据可以看到。收到的网络数据应该是通过某种方式刷新到界面,而不是等到数据返回才刷新页面。当没有网络数据的时候,界面应该可以自成一体,走的通流程,不强依赖网络数据。

在弱网模式下调试是我们必备的功力,因为我们要考虑用户的实施环境通常都不会很好。把经常使用的数据,存到缓存,提高APP的运行效率、界面流程度。同时,我们需要具备收集奔溃日志的功能,这样才能更好的减少崩溃,提高用户体验。

界面卡顿产生的原因和解决方案

iOS界面处理是在主线程下进行的,系统图形服务通过 CADisplayLink 等机制通知 App,App 主线程开始在 CPU 中计算显示内容,比如视图的创建、布局计算、图片解码、文本绘制等。随后 CPU 会将计算好的内容提交到 GPU 去,由 GPU 进行变换、合成、渲染。随后 GPU 会把渲染结果提交到帧缓冲区去,等待下一次刷新信号到来时显示到屏幕上。显示器通常以固定频率进行刷新,如果在一个刷新时间内,CPU 或者 GPU 没有完成内容提交,则那一帧就会被丢弃,等待下一次机会再显示,而这时显示屏会保留之前的内容不变。这就是界面卡顿的原因。CPU 和 GPU 不论哪个阻碍了显示流程,都会造成掉帧现象。

CPU 造成的资源消耗有以下几种:

  • 对象创建
  • 对象调整
  • 对象销毁
  • 布局计算
  • Autolayout
  • 文本计算
  • 文本渲染
  • 图片的绘制和解码

GPU 资源消耗有下面几种情况:

  • 纹理的渲染
  • 视图的混合 (Composing)
  • 图形的生成等

具体可以参考这篇文章

用 Instruments 来检验你的app

时间事件查看器-Time Profiler
在xcode的菜单中选择 product->Profile
我们会看到下面的界面:

Instruments

点击Time Profiler进入。

Time Profiler

下面我们来深究如下的控制面板:

控制面板

以下介绍下配置选项:

  1. Separate by Thread: 每个线程应该分开考虑。只有这样你才能揪出那些大量占用CPU的"重"线程。
  2. Invert Call Tree: 从上倒下跟踪堆栈,这意味着你看到的表中的方法,将已从第0帧开始取样,这通常你是想要的,只有这样你才能看到CPU中话费时间最深的方法.也就是说FuncA{FunB{FunC}} 勾选此项后堆栈以C->B-A 把调用层级最深的C显示在最外面。
  3. Hide System Libraries: 勾选此项你会显示你app的代码,这是非常有用的. 因为通常你只关心cpu花在自己代码上的时间不是系统上的。
  4. Flatten Recursion: 递归函数, 每个堆栈跟踪一个条目。
  5. Top Functions: 一个函数花费的时间直接在该函数中的总和,以及在函数调用该函数所花费的时间的总时间。因此,如果函数A调用B,那么A的时间报告在A花费的时间加上B.花费的时间,这非常真有用,因为它可以让你每次下到调用堆栈时挑最大的时间数字,归零在你最耗时的方法。

找到Detail面板里最耗时的进程,点击进去可以看到代码,观察是否有异,如此便可逐步优化应用的运行效果了。

修改

修改好后,在仪器重新运行该应用程序Product—Profile(或⌘I-记住,这些快捷键真的会为您节省一些时间)。
分配工具

分配工具

点击进入

这个时候你会发现两个曲目。一个叫(分配)Allocations,以及一个被称为VM Tracker(虚拟机跟踪)。

内存泄漏有两种泄漏。第一个是真正的内存泄漏,一个对象尚未被释放,但是不再被引用的了。因此,存储器不能被重新使用。第二类泄漏是比较麻烦一些。这就是所谓的“无界内存增长”。这发生在内存继续分配,并永远不会有机会被释放。如果永远这样下去你的程序占用的内存会无限大,当超过一定内存的话 会被系统的看门狗给kill掉。

内存警告是ios处理app最好的方式,尤其是在内存越来越吃紧的时候,你需要清除一些内存。内存一直增长其实也不一定是你的代码出了问题,也有可能是UIKit 系统框架本身导致的。

尝试

自己动手观察下,一切自然明了。

内存泄露
这一类泄漏是前面提到的 - 当一个对象不再被引用时出现的那种,检测泄漏可以理解为一个很复杂的事情,但泄漏的工具记得已分配的所有对象,通过定期扫描每个对象以确定是否有任何不能从任何其他对象访问的。

关闭仪器,回到Xcode和选择Product->Profile

内存泄露

点击进入,运行:

运行

自己动手尝试下,找到右边面板里,如果有黑色标识的方法,进入看看。学习就是多尝试。

篇幅有限,更多的内容我们下次再聊。

如何编写稳定流畅的iOS移动端应用的更多相关文章

  1. DIOCP开源项目-利用队列+0MQ+多进程逻辑处理,搭建稳定,高效,分布式的服务端

    最近头脑里面一直在想怎么样让能让大家基于DIOCP上写出稳定的服务端程序.很多朋友问我,你DIOCP稳定吗,我可以用他来做三层服务器吗? 当时我是这样回答的,我只能保证DIOCP底层通信的稳定. 说实 ...

  2. html5音频audio对象处理以及ios微信端自动播放和息屏后唤醒的判断---可供参考(功能都完整实现了,只是细节还没处理的很好)

    // html模版中的 此处结合了weui样式整合的微信手机端片段代码(不可直接粘贴复制进行使用)里面含有一些php的写法,可直接略过..###重点参考js代码### <div> < ...

  3. HTC one/M7电信802d 毒蛇ViperOne2.1.0/高级毒蛇工具/完美root,精简/更多自定义,稳定,流畅ROM

    ROM版本 HTC One/M7 802d ROM作者 雪狼团队·大盛 http://weibo.com/DaShengdd Android版本 Android 4.2.2 创建日期 2013.09. ...

  4. ele.me在IOS浏览器端启动APP的技巧分析

    ele.me在IOS浏览器端启动APP的技巧分析 巧妙利用后台重定向,在schemes启动时提示用户打开,启动不了APP时能够及时跳转至下载页面. 避免报错页面的出现以及用户还没来的及选择就跳转到下载 ...

  5. iOS 移动端生成工具开发

    代码地址如下:http://www.demodashi.com/demo/11284.html 一.准备工作 编译环境 xcode 用于生成冗余架构代码, 实现生成零耦合架构 二.程序实现 上个月的一 ...

  6. ios移动端浏览器点击事件失效的解决方案

    点击事件失效的原因可能是因为,你用了事件代理了, 比如这样 $(document).on("click",".fd",function(){ }) 这段代码在安 ...

  7. js时间操作getTime(),ios移动端真机上返回显示NAN

    ios移动端,js时间操作getTime(),getFullYear()等返回显示NaN的解决办法及原因 在做移动端时间转化为时间戳时,遇到了一个问题,安卓手机上访问时,能拿到时间戳,从而正确转换时间 ...

  8. 解决ios移动端双击页面下移

    ios移动端在双击弹出层的时候会出现页面下移,露出底层页面的现象 解决办法: <!DOCTYPE html> <html> <head> <meta char ...

  9. 奇艺iOS移动端网络优化实践 | 请求成功率优化篇 原创 Charles 爱奇艺技术

    奇艺iOS移动端网络优化实践 | 请求成功率优化篇 原创 Charles 爱奇艺技术

随机推荐

  1. javaweb查看后台session和request所有的值

    遍历session @RequestMapping(value ="/test2") public String upload2( HttpSession session) { E ...

  2. Frida HOOK微信实现骰子作弊

    由于微信摇骰子的功能在本地进行随机后在发送,所以存在可以hook掉判断骰子数的方法进行修改作弊. 1.frida实现hook java层函数1)写个用来测试的demo,当我们点击按钮的时候会弹出窗口显 ...

  3. Think twice before doing~

    1.遇到任何矛盾,对事不对人. 2.接到朋友等人的求助电话后,一定要先问清楚对方有什么事情,然后再告诉他(她)能不能帮她(他). 3.如果没有十足的把握和必要,就不要轻易说假话. 4.少提自己的私事, ...

  4. Couldn't open CUDA library cublas64_80.dll etc. tensorflow-gpu on windows

    I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_load ...

  5. div 纯数字很长时无法折行解决

    <div style="width:100%;word-wrap:break-word;word-spacing:normal;"> </div> 加上红色 ...

  6. Math小计

    20161231 黄金分割比:短/长=长/(短+长)=((根号5)-1)/2 ≍ 0.618 斐波那契数列前后两项的比值存在极限.设其中三个数为a.b.(a+b),则当项数趋于无穷时有a/b=b/(a ...

  7. jQuery 中 jQuery(function(){})与(function(){})(jQuery) 的区别

    $(document).ready(function(){ // 在这里写你的代码... }); 在DOM加载完成时运行的代码 可以简写成 jQuery(function(){ // 在这里写你的代码 ...

  8. Spring标签<mvc:annotation-driven/>解读

    一.AnnotationDrivenBeanDefinitionParser 通常如果我们希望通过注解的方式来进行Spring MVC开发,我们都会在***-servlet.xml中加入<mvc ...

  9. CAS环境搭建

    实验背景: 系统环境: Windows XP  |  SUN JDK1.6U4 | Tomcat6.0.14 | CAS Server 3.1.1 + CAS Client 2.1.1 主机完整名称: ...

  10. RabbitMQ之window安装步骤

    安装Rabbit MQ Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装Rabbit MQ的前提是安装Erlang.通过下面两个连接下载安装3.2.3 版本: 下载并安装 Era ...