本文是个人翻译记录~并不是技术分享~有想看中文文档的,可以阅览一下~
About Debugging with Xcode
关于Xcode调节器
寻找和消除代码中的问题是开发过程中的一个关键部分。Xcode调试器预置的通用调试有用的功能,你的应用程序启动时自动运行。调试器可以帮助您:
1.确定和定位问题
2.检查运行代码的控制流和数据结构,以查找原因
3.制定一个解决方案,并编辑相应的代码
4.运行修改后的应用程序,并确认该修补程序
你应该熟悉应用程序设计和编程的概念。与一些熟悉Xcode也推荐;看到Xcode的概述。
每年,苹果在全球开发者大会上的几次会议都致力于在本指南中的材料进行调试,并将其添加到有用的技术。这些会话可供您在苹果开发者网站上的苹果开发者库,很容易找到过滤的“调试”
以下新的WWDC演讲的重点使用Xcode调试器:
WWDC 2014:Xcode 6的调试:学习如何应用程序队列工作,探索和解决用户界面,添加自定义快速查找支持。
WWDC 2013:调试与Xcode:检测和修复性能问题使用Xcode的图形调试器。
WWDC 2013:先进的调试:调试LLDB使用终端和Xcode的图形调试器。
一本好的启蒙书是David J.Agans写的叫做《The 9 Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems》
Quick Start
快速开始
设想一下:你有一个成功的应用程序,你正在添加一个新的功能。单击“运行”按钮,在工作区中的工具栏和您的应用程序成功生成后,运行你的应用程序并启动Xcode调试会话。
当应用程序运行时,Xcode窗口调整为打开调试区的底部和调试导航左侧的调试。在调试导航器中,调试仪表有助于监控您的程序使用系统资源。你开始练习你的应用程序,并使用一些新的代码,你只添加到显示图片或图…没有什么显示。
现在你应该做什么?
开始准备调试!
在调试中最重要的事情是分析代码的逻辑,或控制流程,并确保应用程序提供正确的数据。逻辑问题的应用程序表现出意外的行为:没有发生(如在假设的情况下,如上所述),错误的事情发生,或应用程序崩溃。执行不正确操作的代码经常向用户呈现错误的数据;想象一个计算器上的按钮按钮,添加1和1,并获得结果20。当你看到一个问题,以确保应用程序的行为在计划之中并显示出正确的结果呈现给用户。
在你的假设的情况下,你的新代码似乎没有被执行。你还不知道这个密码是不是没有打,还是没有产生一个输出。但是你知道有什么不妥,你有一个错误。
其他问题的情况更难以发现。在调试程序中使用一个应用程序可以让你有机会使用调试仪监视系统资源的使用。注意图形的形状,并考虑你应该期望看到的应用程序运行和代码的各个部分的运行。 例如,如果你看到在中央处理器或内存表中出现了意外的尖峰,例如,这些可能会显示更为微妙的问题。
单击一个规范,打开一个更详细的报告,为一个更高分辨率的视图。
在这两种情况下,你的新代码,不在你的期望内和在调试仪表的意外迹象,你可能不会立即知道问题的原因。不过,你已经有一些信息:
在你开始添加新功能之前,应用程序的行为是正确的。
应用程序的行为正确的点,你使用该应用程序的用户界面来运行新的代码。
你知道你在源代码中添加了什么新的代码。
为了进一步隔离这个原因,可以在代码中设置断点。
使用断点
断点是一个多功能的解决方案,用于检查一个运行的应用程序。
断点中断正常的执行,以便您可以使用调试栏控件来运行您的应用程序,以检查每一行代码的控制流和状态变量。当你的程序遇到断点,调试器暂停应用程序的主窗口,切换到Xcode与源定位为你检查,并填充变量视图和过程视图和导航的调试工具在暂停应用程序的状态。断点有几个功能,您可以使用修改它们的行为,使您更容易收集信息。在运行应用程序之前,可以在源代码中添加断点,可以在运行时将它们添加到代码中。
插入断点:
1.在源编辑器中定位源。
2.点击资源编辑器槽旁边的线在你要暂停的部位。
创建一个文件和一个行断点,默认情况下是可用的。
在调试栏中,您可以使用各种方法,如在调试器中看到的控件。通过手动的一段代码来检查你的代码,它也可以是耗时的。一旦你在你的代码中放置一个断点,你可以设置它以不同的方式操作,以提高你的调试效率。控件请单击“断点”以显示上下文相关的菜单,然后选择“编辑断点”。
您可以在一个条件的基础上配置断点以中止该程序。因为你的应用程序正在运行时,断点是活动的,你可以使用任何代码或变量在你的应用程序,在该点的源点的激活,以测试一个条件的范围。
断点条件在很多方面都是有用的。举个例子,说你的新功能依赖于一个变量的状态。你注意到当一个问题发生时,你检查一个变量的应用程序在一个断点处停顿,这个变量总是有一个特殊的异常状态或其他不寻常的值。一旦你知道,你可以设置一个断点条件来监视变量和暂停应用程序时,只有当变量具有该值。
断点的另一个有用的功能是触发一个动作的能力。
鉴于上述情况,循环递增和变量需要达到一个特定的状态,也许你有兴趣知道每次循环执行是该变量的值。你可以设置断点操作打印到控制台变量描述在每一次通过循环使用LLDB命令po(po是提供LLDB缩写为“打印对象”命令)。
您的代码中的断点用断点导航器管理的。
使用断点导航器,你可以看到你的代码,所有的断点编辑断点,启用和禁用它们,并在Xcode中经营范围变化。要启用或禁用断点,请单击“断点导航器”或“源编辑器”中的“指示器”,一个“灰色”指示指示该断点被禁用。
要删除一个断点,当您完成使用它,做以下的一个:
1.把它拖到源代码编辑器中。
2.选择在Breakpoing Navigator和按下删除。
3.控件点击它(在源代码编辑器或断点导航器),选择删除断点。
您可以在同一时间启用或禁用多个断点。例如,你可能要做的是,例如,你确定在代码的不同部分的几个问题。
单击“断点”行中的断点行将源程序移动到断点位置的源编辑器中。
有时,当您已经放置了一组断点,调试一个问题,但暂时需要运行您的应用程序,而无需暂停,这样你就可以达到这个问题,你很可能会出现问题。停用或激活所有断点,断点调试栏点击激活按钮。
注
断点激活按钮不更改断点的启用/禁用设置。所有的断点保持在地方,当激活时,启用或禁用,因为它们是在被激活之前。
调试器中的控件
调试导航程序可以帮助你检查应用程序的控制流。当应用程序被一个断点停时,调试程序显示应用程序的执行所产生的最后的值。下面的调试仪表是过程视图,它可以被设置为显示你的应用程序的运行状态,由线程或队列组织。
调试区在Xcode的主窗口的底部包含三个窗格:调试栏,变量视图,与控制台。
在调试栏中的分布控制
调试栏包含隐藏和显示调试区、断点激活按钮和继续/暂停按钮的控件。当应用程序被暂停的一个断点,点击继续按钮恢复程序。
下一步的继续/暂停按钮是一组三个按钮,让你的应用程序。他们的基本操作是一步一步的指令,一步一步的指令,并走出一条指令。如果你把鼠标放在这些按钮上,交替的步进模式会出现,当你点击时使用修改键:
你在代码行代码前设置了一个断点,这是导致问题的问题。这个暂停应用程序,这样你就可以检查变量。然后,你一步一步的应用程序,看看变量的状态如何变化,进入,进入,并在所需的代码行。一旦你完成了检查,你点击继续/暂停按钮恢复应用程序的正常运行。
注
调试栏的分步控制也可在调试菜单中,并有键盘,使他们的使用效率和方便。默认键绑定可以使用Xcode Preference>Key Bindings。
调试栏中的其他按钮更专业化。调试视图层次结构中讨论的按钮。在这2个按钮的右边,进程/线程/堆栈帧跳转栏使您可以直接进入暂停应用程序中的堆栈帧,一个有用的替代方式来移动与调试导航程序视图显示一起运行的。
在下一节中,您将看到如何调试区域的可变视图允许您检查变量,但经常调试一个问题的最好方法是尽可能多地查看问题区域周围的源代码。这是当你使用隐藏/显示按钮来隐藏调试区域,只留下调试栏可用于步进源编辑器。你可以再次打开“调试区”,再按“隐藏/显示”按钮。
变量视图检查变量
在调试区内使用变量视图检查变量,并确定其状态。
正如你可以从图中看到的,变量视图窗格列出了在应用程序暂停的断点处的每个变量的可用性。下一个披露三角形是一组图标,表示变量的种类,然后变量名。名称后面的变量摘要表示当前值。当你在调试栏中使用步进控件来执行你的应用程序,你可以看到源代码中每个操作导致的变量值。
在变量视图窗格,左下角是一个过滤器的弹出菜单,默认设置为自动。此设置限制的变量在查看那些通常被认为是大多数调试有趣的,但是你可以设置变量视图显示所有变量(包括全局变量,静态,和寄存器)或只是局部变量。
对于复杂的变量结构和对象,你可以通过单击“信息披露”的三角形来钻入变量的所有组件中。这允许你看到变量的每一个细节的一次,以及他们如何改变你的应用程序。
过滤器旁边的弹出式菜单是快速查找按钮 ,和打印的描述,你在列表中选择一个变量,单击这些按钮,在弹出的窗口中显示出来。快速查找按钮产生一个图形化的渲染与尺寸和/或价值信息,根据选定的变量的类型。当你试图看到一个复杂的对象,以及它是如何被绘制或渲染的时候,快速的图形化渲染就特别有用了。下面是快速查找按钮被用来在变量视图中显示一个UIBezierPath对象实例:
注:
快速查找显示系统提供的对象类型和你的对象类型。查看更多信息的快速查找数据类型。
打印描述按钮提供了有关该变量的文本信息,相当于使用命令在控制台中的命令。当你点击打印描述按钮,它发出的PO输出到控制台以及显示在弹出窗口。
对于许多开发人员来说,最好的方法是在调试器中暂停时尽可能多地查看源代码。你可以在源代码编辑器中直接隐藏调试区域和工作,使用快速查找和打印描述按钮来检查变量。按住鼠标在一瞬间源编辑器一个变量和一个弹出窗口,变量将显示在变量查看相同的信息出现。你可以打开“信息披露”的三角形,再以变量的角度,看到一个复杂变量的组成部分,等等。弹出式窗口也有快速查看和打印描述可用按钮就好:点击它们具有相同的效果,点击在变量视图。
例如,此图显示了一个CGPoint变量进行描述的打印按钮:
正如你可能期望,打印描述按钮输出显示在一个弹出窗口,在控制台。
大多数的时间,您使用的变量视图,快速查找,并打印描述工具来检查变量值时,你的调试,确保他们的预期。然而,有时,你可能想尝试改变一个变量的值,在fly中看到,纠正了一个问题,而不必经过一个全面建设周期。这是在源代码编辑器中使用弹出窗口在变的容易做:将鼠标停留在一个变量直到弹出窗口出现,向下钻取到变量使用三角形你想要的变量,然后双击该值。记住,改变一个变量的值在fly中经常有一点风险,因为你正在改变运行应用程序的状态,这可能会产生副作用,但对某些类型的调试它可以提供你所寻找的信息。
理解控制台
Xcode调试器区包括控制台视图。控制台视图是一个终端,如命令行环境,在调试会话正在运行时,记录从应用程序和调试器中输出的。当你运行、中断和检查变量时,你可以使用控制台来收集打印的变量值。在控制台视图中的值始终坚持整个调试会话期间,您可以看到在整个会话期间生成的输出列表。当您完成一个会话并重新运行该应用程序的另一个会话,该控制台被清除,所以它总是在一个调试会话开始时开始空。但是,您可以通过向报表导航器和检查存储在那里的调试会话的内容来回顾过去的调试会话中的控制台的内容。
Xcode调试器使用LLDB,低级别的调试引擎,发挥其功能。控制台可以直接使用LLDB命令行界面,你可以在控制台视图中使用任何LLDB命令来补充或扩展Xcode调试经验。
LLDB是一个功能强大的调试环境的许多功能。学习使用LLDB通过阅读LLDB快速启动指南的基础知识。在调试导航仪研究回溯总的情况在本章前面所述,你启动应用程序运行按钮。你试图调用你添加的新代码,并没有发生什么。现在,您已经添加了一个断点,新的代码应该从并尝试再次调用代码。Xcode调试器已经停了你的应用程序在该位置和人口变量视图在调试和调试导航仪的应用程序的当前状态。你很可能会先去看一下变量及其值。变量视图,快速查找,并打印描述工具给你第一次看的应用程序的状态。需要解决的下一个问题是“代码怎么会在这里?“要回答这个问题,您可以使用调试导航程序视图窗格。当程序停在断点,调试器”转向“在调试导航过程视图窗格中的程序流程,介绍给你。一些定义将使这一明确:栈帧是一个调用方法的实例。“平仓”意思是“查看包含你的断点的方法,然后将堆栈框架指针和调用站点的方法进行跟踪。”。堆栈帧解开这个时尚的序列称为回溯。默认情况下,这个视图是由当前堆栈帧的线程来组织的,在源代码编辑器中,程序计数器的位置在断点处突出显示。(调试仪已被隐藏在这个例子中,调试导航仪使用高亮显示的按钮,让你集中精力在过程视图显示回溯。)
回溯可以让你了解在你的应用程序的控制流。在“调试导航程序”视图窗格中显示每个堆栈帧的图标标识。图标告诉你在编译代码的堆栈帧是从哪里来的。有用户代码图标,基础框架,它或UIKit框架,图形框架,等等。调试器检索和在这个充满历史执行接头,甚至包括堆栈帧不再记忆。
这一观点的回溯,你可以看到你的应用到目前的状态,在断点处暂停。看上面的插图:
该应用程序是停留在你的源代码在_plotaccel,这在线程5执行。
这个代码被一个系统函数调用,这是一个被调度的异步回调的一部分。
一些系统堆栈帧省略视图虚线代表他们。你可以通过选择最左边的按钮在滤棒在调试导航仪底部显示这些堆栈帧。
虚线下面的堆栈帧显示了被称为代码的工作线程的开始。
下面,你可以看到块异步排队中记录的回溯。
记录显示,这一块是回溯awakefromnib入队时,可能在应用程序开始。
当你点击在回溯堆栈帧的源代码编辑器,跳跃在源或在反编译的二进制可执行文件,点。对于代码的堆栈帧,可以看到源代码。如果帧在内存中,您可以看到变量值;如果堆栈帧在内存中不再是,它是一个记录堆栈帧的变量值是不可用的。
注
在调试导航程序视图中,如果一个堆栈帧的图标是颜色的,则堆栈帧是内存中的。灰色图标旁边的堆栈帧表明,堆栈帧是不再在内存中,和调试导航已检索堆栈帧通过分析记录的呼叫历史;调试器不能重新创建的变量值从记录的呼叫历史。
使用调试导航和回溯,你可以看程序的代码已经沿着期望的路径移动到断点或是否偏离你的预期要。跳到用户代码在回溯当你有问题时,你可以设置新的断点,停止应用程序在前点看看它通过检查变量沿着路走歪了。
如果你的新代码不运行或显示因为条件没有实现正确的回溯,找到正确的点,设置一个断点,说明问题,单击运行/暂停恢复正常运行,然后执行,应该重新运行新的代码的作用。这个时候停止在程序流程和检查变量,然后一步一步的应用程序,直到你找到问题的原因,检查的变量一路上。
循环调试过程
调试是一个反复的努力。你发现一个问题,你设置断点来帮助你定位在源它发生,你检查的回溯和变量来评估他们的状态和问题的原因,和你想出一个解决方案或修理。有了一个潜在的解决方案,你做出了改变的来源和重新运行该应用程序,看看这个问题是否得到解决。如果测试显示这个问题仍然存在,你就重复这个循环,直到你把正确的固定放置到位。
当问题被解决时,您可以禁用或删除您在其调查中使用的断点。你不想让他们在你继续下一个问题的方向前进。