okeyang's blog

Xcode8新增Debug方法

| Comments

今年的WWDC介绍了不少新的调试方法,可以更加快捷便利的定位问题、分析问题、解决问题,下面就简单介绍一下。

循环布局检测

当你进入某个界面或点击某个按钮后,发现屏幕不再响应事件,然后进入无限等待,debug下可以看到CPU满负荷,RAM也不断增加,那么有可能就进入了循环布局状态。

举个栗子

先说一个简单的循环布局的case,如下图所示。

最底下的subview A在layout时更新superview B的bounds,B因为不在layout状态,所以会使superview B调用其superview C的setNeedsLayout()方法,然后进入layout状态,此时C重置B的bounds,B又使A再次layout。因为对B的bounds设置不一致,导致循环下去。

检测方法

可在Launch Arguments中添加-UIViewLayoutFeedbackLoopDebuggingThreshold,设置循环布局阀值,如100,然后当循环布局次数超过阀值时会抛出异常,此时通过po [_UIViewLayoutFeedbackLoopDebugger layoutFeedbackLoopDebugger]可输出详细信息。

parray poarray

看名字就能猜到,这是针对数组的打印信息命令。在传统的C数组中,是无法通过数组本身知道其长度的,所以一直以来lldb都不能很好的打印C数组,parraypoarray解决了这个痛点,可以通过指定打印个数来打印数组的多个内容。

需要注意的是这两个命令都是针对C数组的,区别是以p还是po的方式打印数组内容。另外只能打印堆空间存储的数组。

1
2
3
4
5
6
// 以"p"方式打印内容
parray 3 intArray
parray `count` intArray    // "count"为代码中变量
// 以"po"方式打印内容
poarray 3 objectArray
poarray `count` objectArray

register read

register命令并不是新增的,一直以来都有,但在WWDC2016Session 417 Debugging Tips and Tricks中重点说了一下,实为解决一类疑难bug的利器,在这里也简单介绍下。

平时是否有过crash在没有源码的第三方库或系统库中,而检查自己代码又没有发现任何问题?那么试试register命令吧,可能会有意向不到的效果。

通过register read可以读取当前状态下寄存器存储的变量,在没有源码的情况下运气好就可以获取到一些非常有用的信息,毕竟很有可能是你传入的某个错误值导致的最终crash,而这个值就可能从寄存器中取到,从而快速定位原因。

register还有一个非常有用的特性,当刚进入某一函数时,可通过register read $arg1 $arg2 ...读取函数的各个参数值,如下:

启动各过程耗时检测

在WWDC2016Session 406 Optimizing App Startup Time中,详细介绍了App启动,即进入main()函数前做了什么事儿,以及如何优化各个过程,另外提供了DYLD_PRINT_STATISTICS环境变量方便测试各个过程耗时。

然后在启动时会打印如下所示信息:

Apple给出的建议是:

在最新的设备下,启动时间控制在400ms以内

如果你的App不达标,那么就开始着手优化吧!具体各个过程的优化原理及方法,限于篇幅就不再介绍了,感兴趣可以看看Session 406 Optimizing App Startup Time

runtime issue

Xcode8新增了运行时问题的检查,如下:

runtime issue主要分为3类:

  • 线程问题,加入了Thread Sanitizer检测线程问题
  • UI布局问题,主要是约束冲突
  • 内存问题,检测内存泄露

Thread Sanitizer

Address Sanitizer之后,Xcode8中加入Thread Sanitizer用于检查一些线程问题,并会显示在runtime issue列表中,使用Thread Sanitizer需如下图所示开启,重新编译运行后即可。

Thread Sanitizer主要检测以下问题:

  • 使用了未初始化的mutexes
  • Thread leaks,如缺少pthread_join
  • 在signal handlers中的不安全调用,如调用malloc
  • 在错误的线程中做unlock
  • 最重要的一点:Data races问题

凡是通过Thread Sanitizer检查出来问题,都代表着有很严重的隐患,那么,赶快修复吧!

Static Analysis

Xcode8对Static Analysis做了近一步加强,新增以下问题检测:

  • 本地化检查
  • 内存泄漏检查
  • Nullability检查

本地化检查

首先需要如下方式开启,Static Analysis将会检查UI元素的文字设置是否使用了NSLocalizedString

内存泄漏检查

主要检查的是dealloc中内存的释放。这个功能来的有点晚,是一个给MRC使用的功能,在ARC基本普及的今天已经显得不是太重要了,当时没能雪中送炭,如今只能锦上添花了。

Nullability检查

这项检查是针对设置nonnullproperty返回值。当设置为nonnull,但返回值可能为nil时则会有相应warning。

参考链接

  1. Section 236 What’s New in Auto Layout
  2. Section 406 Optimizing App Startup Time
  3. Section 410 Visual Debugging with Xcode
  4. Section 412 Thread Sanitizer and Static Analysis
  5. Section 417 Debug Tips and Tricks

Comments