所在的位置: swift >> swift发展 >> 在iOS中调试

在iOS中调试

在Xcode中充分利用LLDB

在Xcode在开发任何类型的程序时,调试是开发人员最重要的过程之一。它允许您检测和删除现有和潜在的错误。因此,iOS开发也不例外。

像你们中的许多人一样,我进入令人惊叹的调试世界的第一种方法是使用非常有名的print语句。但是,这种调试方式可能会让人不知所措,并且您的代码可能会因多行print语句而变得混乱。

打印语句示例断点

但有时,磨片试图调试的东西,我们希望看到的是在我们的计划中的每一步怎么回事。当然,我们可以做到,这就是断点出现的地方。断点是我们程序中代码将停止执行的点。在Xcode中,我们可以使用LLDB(低级调试器),这是Apple平台上开发人员的默认调试器,并制作出我们甚至无法想象的很棒的东西。

断点po命令

在我们设置断点并且我们的程序停止执行之后,我们可以使用命令来获取我们需要的所有信息。最常见的命令可能是po,它是expression--object-description—-命令的别名。该命令为我们提供了我们正在检查的对象描述。在下面的例子中,我们打印了我们类型的一个实例的文本表示,在这种情况下是aBook。

我们有系统运行时提供给我们的默认对象描述,但我们可以使用协议CustomDebugStringConvertible和变量创建我们自己的描述debugDescription。例子:

自定义调试字符串可转换

和po命令可以做的比这还要多。它几乎可以计算您将在程序中编译的任何表达式。看下面的例子,我们使用相同的图书实例,但这次,我们计算图书发布后经过了多少天。

使用po命令执行代码

p命令

我们必须打印变量的第二种方法是使用命令p,它是expression--.我们通过这个命令得到的信息与结果基本相同,po但是,您可以想象,这次打印的对象没有描述。主要区别在于,p在幕后制作一个过程,而po不是。这个过程称为动态类型解析,我将通过一个例子来解释:在Swift中,代码中类型的静态表示在运行时可能与动态类型不同。在这个例子中,我们可以看到实例maria的静态类型是Human,但是在运行时,这个变量会有一个类型为Student.如果我们尝试打印实例玛丽亚使用p,我们得到类型的实例Student,因为p是计算结果的动态类型;它为给定变量提供了更准确的类型。

点对点

但是,不进行强制转换就无法访问实例的属性。

铸造实例以访问其属性v命令

还有第三种打印变量的方法,就是使用v命令。该命令的输出与相同p,但主要区别在于该v命令不编译代码,因此速度非常快。以前面的例子为例,v我们不需要进行强制转换,因为它从内存中读取实例的值,然后多次使用动态分辨率来做出更好的解释。

v命令

所以,在我看来,我会在以下场景中使用这个命令:

·po如果你想编译你的代码并获得对象描述。

·p如果你只想编译你的代码

·v如果要打印当前堆栈帧中的变量

自定义断点

现在是时候讨论断点的威力了。让我们用一个简单的应用程序看一个更实际的例子。这个应用程序计算一张支票的总和加上小费百分比,然后打印结果,但正如你所看到的,其中有一个错误。

臭虫

我们期望的结果当然是美元。因为我们想在美元的支票上加上10%的小费,但总数却是美元。让我们使用断点来看看发生了什么。

点击计算按钮后执行的代码

此时您可以看到我们正在打印数量而不是amount+tipValue.但是因为我们不想进行此更改,编译,然后重新运行应用程序以确保我们是正确的,所以我们可以编辑断点并即时进行更改。

我们双击断点进行编辑

我们添加以下表达式:expressionamount=amount+tipValue

我们单击评估操作后自动继续选项。这会触发表达式并继续执行程序。

自定义断点

现在我们点击计算按钮,我们看到总金额打印正确。

第一个错误已修复

问题已修复使用调试器修改我们的视图

现在我们有第二个要求。我们想将我们的计算按钮和总标签(都在堆栈视图中)向下移动点到底部。

要修改的垂直空间

当然,既然我们是调试开发人员,我们也想用控制台来做这件事。为此,我们需要获得堆栈的内存地址,我们可以使用代码可视化视图调试器来获取该地址,但我们也可以使用控制台!

要获得所有与包含在我们的视图控制器的子视图的信息视图,我们将使用这个新的命令:expression-lobjc-O--[`self.view`recursiveDescription]。

随着-lobjc-O我们告诉调试器,我们将要运行的Objective-C代码。

获取要修改的栈视图地址

有了结果,我们可以轻松找到堆栈视图的地址。

接下来我们要做的就是使用一个名为的函数来检查这个堆栈视图的描述unsafeBitCast。然后,我们可以访问堆栈视图的所有属性。

打印堆栈的框架

拥有所有这些自由,我们可以简单地更新堆栈的框架。我们将点添加到y框架的值。

修改stackview的frame

等一下,什么都没发生。这是因为在调试器的任何用户界面的变化之后,我们需要手动触发呈现更新使用类方法我们认为flush()对的CATransaction类。

我们现在已经完成了第二个要求

正如您所看到的,LLDB是一个非常强大的工具,它可以帮助我们作为开发人员在调试代码、修复问题时提高我们的生产力并改善我们的时间,甚至只是在发现我们可以做的所有事情时发现乐趣,而无需多次重新编译和重新运行我们的应用程序.

PS不要忘记在代码中添加您的错误修复。




转载请注明:http://www.aierlanlan.com/tzrz/8957.html