iOS调试技巧总结

调试技巧总结

 

1.断点

  1.1 普通断点

  1.2 全局断点(Global BreakPoint)

  1.3 条件断点(Condational Breakpoints)

2.  打印的艺术

  2.1  NSLog

  2.2  开启僵尸对象(Enable NSZombie Objects)

3.  进击的码农

  3.1  Console(lldb 命令)

  3.2  Profile(instruments)

  3.3  Xcode视图调试

 

1.1 普通断点  如图3
html

基本的断点操做以下python

图4c++

 

点击那个黑列列就建立了一个断点,再次点击就临时取消这个断点(可是不删除),长按那个断点拖出去就删除了,固然也能够右键那个建立的断点,会弹出相应地菜单。git


固然也还能够监视某个变量!如图5github

在对象视图中,右键某个对象,点击“Watch ‘XXX’”就完成XXX对象的监视了。web

这里我监视了lab这个UILabel的变量,每当这个变量进行更新它的信息就会被打印到控制台。swift


好吧!咱们最基本的建立断点的工做已经学会了,Xcode舒服在什么地方呢?就是不分Debug模式和Run模式的,能够说是无缝切换的,你只要没有建立断点,那么就是Run的正常模式,若是建立了断点而且运行到断点处,就自动进入Debug模式咯,不像某EC开头的IDE,控制面板就像开飞机的同样,几万个按钮觉得很强大,其实只用了Run和Stop,还有什么Debug模式,App模式……,果真Xcode的优越感在对比中更增强烈了,舒服到极点呀,就像夏天的海风拂过菊花,嗯是的 就是那种感受!xcode

咱们建立好了断点,运行到断点就自动停下来了,像这样:app

图6框架


 

1.2 全局断点(Global BreakPoint)


有时候在程序出错的时候不能能准肯定位到奔溃的那一行代码,而是直接跑到main循环或者Appdelegate里面, 或者会给你这样的提示:EXEC_BAD_ACCESS:,


图7

在Debug导航面板进行上图的操做,你就创建了全局断点,这样只要遇到错误,debug程序就会自动定位到栈底的信息,也就是你最早出错的代码的那一行

 

 1.3 条件断点(Condational Breakpoints)


咱们来看一段代码图9

 

在Debug导航面板进行上图的操做,你就创建了全局断点,这样只要遇到错误,debug程序就会自动定位到栈底的信息,也就是你最早出错的代码的那一行

 

 1.3 条件断点(Condational Breakpoints)


咱们来看一段代码图9


这样只有遍历到c==“H”的时候 断点才会被触发。图10

有些童鞋的钛合金狗眼已经看到了编辑断点那里有一个Action的东西,那是什么呢?

这个是很是强大的,能够在你断点的位置,执行各类操做,好比执行脚本命令,控制台命令(能够制定调试信息自定义保存)、打印信息等,

博主最喜欢的就是这个Log message啦,简单粗暴!根本就不须要print啊NSLog嘛,直接在断点的Action打印就行了(其实这个是Xcode和调试器结合的高能产物,下面再介绍)。具体能够这样:

图11

其实刚刚博主撒谎了,博主最喜欢的Action并非Log Message,而是Sound,顾名思义嘛,断点射在Bug上,这样遇到断点就会发出声音,听到我本身设置的声音,我就知道是什么Bug了,听声识Bug,呵呵,EXEC_BAD_ACCESS的错误我设置成了波多野老师的声音,unrecognized selector send to instancd的错误我设置成了苍老师的…… 不要问我系统怎么没有吉泽明步的声音,我根本就不知道谁是吉泽明步。

固然还有更增强大的条件断点就是这货啦  图12

添加以后在 Symbol 一栏输入 viewDidLoad。

这样一来,在程序中全部的 viewDidLoad 方法被调用时都会触发断点。 图13



固然,咱们也能够仅仅为特定的某个类的方法添加断点。在 Symbol 一栏输入 [ClassName viewDidLoad] (Objective-C) 或 ClassName.viewDidLoad (Swift) 便可。

好比:unrecognized selector sent to instance 0xaxxxx 这种错误,这个instance能够这样快速定位    图14

 

 

2. 打印的艺术

尽管ARC已经让内存管理变得简单、省时和高效,可是在object的life-cycles中跟踪一些重要事件依然十分重要。毕竟ARC并无彻底排除内存泄露的可能性,或者试图访问一个被release的对象。

          NSLog 能够用宏覆写NSLog方法(若是不记住的话,能够直接在打印的前面作标签,而后想知道哪里打印的用全局搜索你的标签,就能够定位到,但注意标签的惟一性,尽可能少重复的):


//若是是在debug阶段,则打印  不然在上线阶段 则为空了

#ifdef DEBUG


/**  关于NSLog的输出 改造,用法不变   */

#define  NSLog(format,...)  do{ \

fprintf(stderr," <%s : %d>   方法名%s\n",\

[ [ [NSString stringWithUTF8String:__FILE__] lastPathComponent] \

UTF8String], \

__LINE__,__func__); \

(NSLog)((format),##__VA_ARGS__);\

fprintf(stderr,"-------------------------------------------------------------\n"); \

}while (0)


#else


#define NSLog(format,...)


#endif

 

关于宏的威力 你们能够乱入个人博文《 IOS中的预编译指令的初步探究》

这样打印出来的东西才像话嘛(其实NSLog的打印是很是低效的,甚至比printf低100倍,感兴趣本身翻翻苹果手册咯)。 


使用objc语言(强类型)而且用NSLog打印的时候,经常搞不清楚NSLog(@“%?”,xxx) xxx这种类型该是什么什么类型输出,应该是%d呢仍是%@亦或是%f???傻傻分不清楚~,因此玩转NSLog你应该要知道如下这几个全局方法!

图17


2.2  开启僵尸对象(Enable NSZombie Objects)


Xcode能够把那些已经release掉得对象,变成“僵尸”,当咱们访问一个Zombie对象时,Xcode能够告诉咱们正在访问的对象是一个不该该存在的对象了。由于Xcode知道这个对象是什么,因此可让咱们知道这个对象在哪里,以及这是何时发生的。


具体这样作:图15



注意:NSZombieEnabled只能在debug下使用,若发布时务必去掉

 

3.  进击的码农

         3.1  Console(lldb 命令)


咱们如今正在使用着世界上最好的c、c++、oc、swift的编译器——LLVM,lldb就是这个世界上最好的LLVM的调试器!

首先!你得先crash或者把程序断下来!直到你看到图16的(lldb)字样出现,你就能够敲命令了~~

每次你想查看变量,常量,你要从新写NSLog去打印,而后从新编译,去执行,重头开始?太累了,有了lldb你只要这样  print c 就能够了

图18


当你有一个switch语句,你为了测试每个case,你都要制造假条件去测试;有一个if…else…语句,你为了测试不一样的状况,你要硬编码写了不一样的状况,编译好几回为了测试每种状况……以上的这些状况,只需一次编译,使用lldb的thread命令,伪造返回值,欺骗寄存器,就能够为所欲为的作完全部测试了。


lldb真的很强大,博主没有骗你,这篇博文到此的全部调试技巧lldb均可以实现,各类断点,各类打印,调用python插件,运行中断,操做硬件底层,控制程序运行线程……lldb均可以作到!仿佛lldb就是另外一个强大的世界!!!

这里有很好的文章!

《The LLDB Debugger》

《About LLDB and Xcode》

《LLDB调试命令初探》

《与调试器共舞 - LLDB 的华尔兹》



3.2  Profile(instruments)

图19


instrument里面包含了不少工具,内存溢出分析,性能分析,各类分析……


在使用leaks以前你们能够试试这个“Analyze”
图21


analyze能够快速的发现你的代码中release的问题,以及继承过程当中的父类方法缺失等等问题!若是analyze都经过了,那么就可使用leaks工具

图22   (allocations : 分配  配置)


若是提示某一个对象有侧漏的风险,你还能够这样弹出侧边的拓展细节
图23


直接点击方法就能够直接进入代码部分了!!
是否是很简单粗暴呢!固然还不少其余工具,不过叫作篇幅的东西老是限制人,诶 真蛋疼~真的还想多说点的 
想要更多了解instrument 你们能够看看这篇文章!
《How to Use Instruments in Xcode》

 

3.3  Xcode视图调试

抄袭自《View Debugging in Xcode 6》
苹果在Xcode 6中作了很多明显的改善和优化,视图调试就是其中之一。一般,App用户界面的行为不会符合开发者指望的那样,好比或者不展现视图,或者没有正确地展现。本文讲解如何使用Xcode的新的视图调试功能来简化开发者对问题界面的确认和修复。

1.Demo 工程

开始之初先从github(https://github.com/tutsplus/ViewDebugging)上下载示例工程并打开ViewDebugging.xcodeproj。该工程包含一个简单的包含少数视图控制器的可点击的应用程序、应用程序委托以及一个storyboard。该app是为iPhone而设计,但受益于iOS 8的自适应布局,因此界面展现在任何设备上都没有问题。

您刚刚下载的应用程序示例工程是一个简单的to-do list应用程序,包含可查看其余信息的简单屏幕,好比该示例工程中的项目数,用户头像以及@***的推特操做。点击Xcode左上角的运行按钮将展现在iOS模拟器中运行的应用程序。
图24


很快会注意到用户界面中存在问题-表视图中没有展现任何数据。在工程导航面板中打开FirstViewController.swift并找到如下代码:

var mockNotesDataSource: [String] = ["Do some laundry", "Finish homework", "Walk the dog", "Learn about view debugging"]{
didSet{self.tableView.reloadData()}}

 

能够看到mockNotesDataSource变量是表视图的数据源。使用Swift的属性观察者功能,在数据源发生改变时,表视图会自动从新加载。经过查看以上代码片断,你会发现应该应用中应该有4个项目须要展现,但如今不展现数据就说明某些地方出现了差错。

启用视图调试

问题彷佛与用户界面有关。运行app过程当中,按下底部的Debug View Hierarchy 按钮,或者从菜单中选择Debug > View Debugging > Capture View Hierarchy 来启动视图调试。

图25


启动视图调试后,Xcode会对应用程序的视图层次拍一个快照并展现三维原型视图来探究用户界面的层级。该三维视图除了展现app的视图层次外,还展现每一个视图的位置、顺序和视图尺寸,以及视图间的交互方式。

示例工程在Xcode中的三维视图展现正常,但表视图单元格彷佛有点太宽了。
图26


暂停应用程序调试并在左侧选中Main.Storyboard来修复问题。点击表视图并选中Editor > Resolve Auto Layout Issues > Reset to Suggested Constraints.
图27


编译并再次运行应用程序以肯定用户界面展现正常。点击Debug View Hierarchy按钮更进一步了解视图调试的功能。

视图调试功能

点击并拖拽三维渲染图的任意一边,可旋转或者倾斜用户界面,向左或者向右倾斜可选中某个表视图。

选中后,Xcode会高亮该视图,并在会在右边展现Object 和Size检查器。查看在跳转栏顶部并确认UITableView是右边最后一个项目。
图28

Object 和 Size检查器包括大量有用的信息。过去开发者须要依赖日志语句或者断点来检查视图的配置。

打开右边的Size inspector(规格检查器),下方是Auto Layout,能够看到视图上已经应用了正确的约束。在Object inspector中,咱们能够检查所选视图的属性。
图29

在Xcode的调试区有9个视图调试过程当中要用到的按钮和滑块儿。
图30


从左到右控件排序:

调整视图间距:调整不一样视图间的间距。

展现被剪切的内容:当前展现视图中被剪切的部分。

展现约束:展现选中视图的约束。

重置查看区域:将3D渲染透视图恢复至默认状态。

调整查看模式:选择性地展现3D渲染透视图,好比仅展现内容,仅展现框架以及同时展现内容和框架。

缩小:缩小3D渲染透视图

恢复:将3D渲染透视图恢复至默认尺寸。

放大:放大3D渲染透视图

调整可视视图范围:隐藏视图或展现视图,一步步解析3D渲染视图,向左或者向右滑动滑块儿有相反的效果。

建议花一点时间上手操做下这些空间,并理解各自的用处。

视图层排序

再次编译和运行应用程序,并点击用户界面底部的"More"标签。第一眼看去界面看起来还OK,可是它没有按照开发者的定义准确执行,图片上的模糊效果没有展现出来。咱们能够经过调试视图层次来更好地肯定问题所在。

向左或者向右拖拽视图来查看具体状况,接着将view spacing slider向右拖动。
图31


这样一来,不一样视图间的间距变大了,层次也更加清晰,咱们看到在图片"下方"还隐藏着另外一个视图,选中隐藏的视图,它就是"丢失"的视觉效果视图。
图32


打开Main.storyboard 并选中Second View Controller Scene。在左侧的文档概览面板中,展开Second View Controller的视图对象以查看子视图的排序。

Xcode在文档概览中按照递升顺序堆叠视图,换句话说,列表顶层的视图是视图层次的基础。

修复问题很简单。运行时,Blur Effect View隐藏在Sky Image之下,由于它是视图层次的第一个视图。在文档概览中点击并拖拽 Blur Effect View,结果会以下图展现同样:
图33


再次运行应用程序就能看到模糊效果了。应用程序的用户界面看起来符合设计的初衷。咱们还能够查看iOS模拟器的其余调试功能,看看还完善了其余什么地方或功能。

5.iOS模拟器调试功能

编译并运行应用程序,选中模拟器,从 Debug菜单中选择Color Blended Layers选项。
图34


而后会看到app的用户界面被红色和绿色覆盖,显示了哪些图层能够被叠加覆盖,以及哪些图层是透明的。混合层属于计算密集型视图,因此推荐尽量地使用不透明的图层。
图35


苹果在其文档(iOS Simulator User Guide)中对此进行了注明,并在表视图处理上使用了不透明图层。滚动视图时会有些表现不大好的地方,一个重要的缘由就是使用了混合图层,而若是内容背景是不透明层,那么页面滚动效果就会很是流畅和平稳。

对于这款应用程序来讲,假使用户有数百个项目要展现,可能会出现滚动性能不一致的状况。表视图单元格当前使用的是混合层。因为视图控制器的视图背景是白色,因此无论表视图单元格使用的是混合层或者不透明层,终端用户不会觉察到有什么不同。

打开Main.storyboard并选中To Do list Scene中的表视图单元格属性。在属性检查器(Attributes Inspector)中,向下滚动Drawing分区并勾选Opaque。
图36


在启用Color Blended Layers的状态下编译并运行应用程序。因为表视图单元格如今使用了不透明层,因此会用绿色覆盖,以指示它们是不透明的。

除了标记图层外,还有其余一些有用的功能可帮开发者在iOS模拟器中调试应用。如下是其中一些比较有用的:

Toggle Slow Animations in Frontmost App: 选中模拟器,打开Debug菜单选中Toggle Slow Animations in Frontmost App,该功能能够下降app中动画的运行速度,适合调试包含复杂动画的应用程序。也但是使用快捷键Command-T来操做。
Color Copied Images:该选项能够给绘制时被Core Animation复制的图片添加蓝绿色叠加层。
Color Misaligned Images:若是图片边界没有与目标像素完美对齐,该功能可为图片叠加上一层品红色。若是图片使用肯定的比例大小绘制,那么该功能会为图片添加一层黄色叠加。
Color Off Screen Rendered:.该选项为离屏渲染内容添加一个黄色的叠加层。
不少开发者会忽略接入电话时应用状态栏的设计问题,你能够经过触发通话中状态栏来简单测试。在iOS模拟器中,从Hardware菜单中选中Toggle In-Call Status Bar。

想查看app如何响应事件,可按下Command-T来启用slow animations,并按下Command-Y来展现电话接入时的状态栏。假若你的应用程序使用了导航栏,那么操做系统会为你兼顾到这一起。
图37


除了给视图着色外,还要记住iOS模拟器也能够调试Core Location问题。你能够在特定经纬度模拟设备,

若是你的应用程序使用iCloud来管理数据,你也能够手动触发同步事件。

本文中使用的demo app很是简单,使用文中提到的技术能够帮你在将来节省很多时间。视图调试能够帮你修正不少用户界面中出现的问题。

除了Xcode和InterfaceBuilder以外,使用iOS模拟器的调试功能能够提高应用性能和识别开发过程当中的瓶颈。苹果的人机交互指南(中文版 英文版)强调了积极响应对app的重要性,能让用户以为应用易于使用和操做。苹果对InterfaceBuilder的提高让视图调试变得史无前例的简单。

结语

这篇文章博主花了3个礼拜,断断续续才写完的,当中错漏应该很是多,可是不管如何鄙人以为应该算是配的上豪华套餐的称号了,当中IOS开发的基本、经常使用以及高阶的调试技能都涉及了,可是仍然有不少其余的奇门巧技没有介绍到,主要是可恶的“篇幅”限制住了博主广博的爱,可是不管如何,这篇文章你们暂且能够当作是一个调试技术的目录,由于博主在这里写的讲的很粗浅,你不该该只知足于这篇文章,你若是想要改变世界的话,你应该借着博主的这篇目录式文章深刻地学习与研究!

固然还有Crash的日志、测试工程、以及强大牛逼哄哄的第三方调试库等这篇博客没有涉及到,这是一个遗憾,可是我相信聪明的你会去Google一番的!

还有咱们与逼优鸡的故事才刚刚开始。

相关文章
相关标签/搜索