卡顿

顾名思义,卡顿就是应用运行不流畅的现象,给用户的直观感受就是点击屏幕操作有停顿、响应缓慢、界面卡死等。轻微的卡顿问题会影响用户体验,严重的情况更会造成应用不可用。

卡顿肿么产生的

先来看一段示例代码:

let button = UIButton(...)
button.addTarget(self, action: "handleButtonAction:", f
orControlEvents: .TouchUpInside)

代码释义:创建一个UI Button,当用户点击的时候,主线程会响应及处理点击事件,这里是执行handleButtonAction方法。

func handleButtonAction(sender:AnyObject?) {
let url = NSURL(string: "http://dldir1.qq.com/qqfile/QQ
 forMac/QQ_V4.0.2.dmg")
 let urlRequest = NSURLRequest(URL: url!)
 var response: NSURLResponse?
 var error: NSError?
 var data = NSURLConnection.sendSynchronousRequest(urlRe
 quest, returningResponse: &response, error: &error)
 }

代码释义:handleButtonAction方法发起了一个网络请求下载图片。必然的,这是一个耗时的操作。

在iOS应用中,所有的UI操作及更新都是在主线程完成,并且主线程的runloop是逐个处理用户事件的(当然其他的runloop也一样),所以主线程必须等待上一次事件处理完成后才能继续响应下一次事件。

在示例中,由于在主线程内发起耗时网络请求,主线程只能停止响应接下来的所有用户事件,等待网络请求结束。在等待的这个过程中,应用就停止响应了,也就是出现卡顿现象。

为了更好的理解主线程的runloop,我们来看看iOS应用的运行机制。

QQ截图20150629112727

在 iOS 应用启动后,系统会自动创建主线程并开始运行它的 runloop,监听处理分发事件,当没有事件发生时进入休眠状态,有事件发生时系统会将接收到的事件放在一个队列里,然后唤醒 runloop 依次处理事件。

绝大部分用户感知到的卡顿就是由于主线程阻塞了,在处理某次事件消耗了过长的时间,导致主线程处于等待状态,无法及时响应用户的下一次输入事件。

由于iOS 上的 UIKit 只能在主线程进行处理,导致开发者在开发过程中不经意间在主线程做了一些消耗时间的工作,导致了应用卡顿。

卡顿怎么破

避免卡顿的黄金法则就是不要让主线程干重活,例如网络请求,读写大文件,复杂的运算 等一些耗费大量系统资源及时间的任务。

充分利用好 iOS 的多线程,如 NSThread、NSO peration Queue,GCD 等干脏活,累活,让主线程能及时迅速的响应用户事件。

主线程轻松了,应用就流畅了,用户也就爽了,五星评价还会少么?

那么我们根据上面的黄金法则修改下handle Button Action方法,用GCD 来进行网络请求

func handleButtonAction(sender:AnyObject?) {
let url = NSURL(string: "http://dldir1.qq.com/qqfile/QQ
 forMac/QQ_V4.0.2.dmg")
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE
 _PRIORITY_DEFAULT, 0), { () -> Void in
 var data = NSData(contentsOfURL: url!)
 })
 }

经过修改之后,现在主线程就不会发生阻塞了,迅速的执行完用户的点击事件后,然后等待响应用户的下一次事件。

除了在开发过程中开发者需要时刻牢记黄金法则避免写出阻塞主线程的代码,我们还需要一套监测机制来帮助我们及时的发现应用卡顿,第一时间定位并修复,给用户如丝般顺滑的操作体验。

应用还在开发测试阶段的时候,我们可以通过 Instruments 提供的 Time Profiler等工具进行检测,发现阻塞主线程的代码。那么应用发布后呢?如果碰到用户反馈卡顿,我们又该如何去定位解决问题?

一个比较常见的场景:用户反馈应用卡顿,客服人员反馈给开发,开发要求用户提供更加详细的信息以定位问题,但是问题又来了,很多时候我们联系不上用户啊!怎么办?熬夜加班逐行检查代码,说多了都是泪。

posted @ 2015-08-12 10:59  ~Imp  阅读(328)  评论(0编辑  收藏  举报