Xcode调试器:查看变量的值

117

我的代码在一个UITableViewController中:

delegate.myData = [myData objectAtIndex:indexPath.row];

我该如何在调试器中查看delegate.myDataindexPath.row的值?delegate.myData应该是一个数组,而indexPath.row是一个int。我只能看到delegateindexPath对象的内存地址,但是myDatarow在哪里呢?

alt text


在代码编辑器下方的调试区域中右键单击,选择“添加表达式...”上下文菜单项。在此输入变量,例如delegate.myData,然后就完成了。请检查我的答案:https://dev59.com/7m445IYBdhLWcg3wssXH#70614719 - petrsyn
8个回答

150

谢谢!我尝试了很多方法:"print [myData objectAtIndex:indexPath.row]", "po [myData objectAtIndex:indexPath.row]", "print indexPath.row", "po indexPath.row",但每次都会收到消息“没有名为row的成员”。这个可以用:"print indexPath"和"po indexPath"。所以我尝试使用"[]"代替".":"po [indexPath row]" -> "无法打印NIL对象的描述。""po [indexPath getRow]" -> "目标不响应此消息选择器。" :-( - Manni
4
尝试打印(int)[indexPath row]。 - Andriy
返回翻译文本:po [myData objectAtIndex:(int)[indexPath row]] - Andriy
@VanDuTran 我相信在Swift中,po obj的等效语句是po print(obj) - Chris
这对于查找计算属性的值也非常完美。谢谢! - Paula Hasstenteufel

34

我同意其他发帖者的看法,作为一个开发环境,Xcode应该包括一种简单的方法来调试变量。好消息是,确实有这样一种方法!

在搜索并没有找到如何在Xcode中调试变量的简单答案/教程后,我去探索了一下Xcode本身,并发现了这个(至少对我来说)非常有用的发现。

如何在Xcode 4.6.3中轻松调试您的变量

在Xcode的主屏幕上,通过单击屏幕右上角的按钮,确保查看底部的Debug Area。

调试区域按钮

Xcode 4.6.3中的Debug Area

现在通过单击代码区域的边框来设置断点-您希望程序暂停的代码行。

断点

现在,在调试区域中查找此按钮并单击中间的按钮。您会注意到您的区域现在分成两部分。

分离调试区域

应该看起来像这样

现在运行您的应用程序。

当程序执行期间达到第一个断点时,您将在左侧看到所有可用于该断点的变量。

搜索字段

您可以展开变量左侧的箭头以获取更详细的信息。甚至可以使用搜索字段来隔离您想要的变量,并随着进入断点的范围而实时查看其变化。

步入

在调试区域的右侧,您可以使用鼠标右键单击所需的变量,并将其发送到打印输出,以便按照您的要求进行排版。

Contextual Menu

正如您所看到的,该上下文菜单充满了非常有趣的调试选项。例如监视已经建议使用输入的命令,或者甚至编辑值…会更改您的变量的运行时值!


21

此外,您还可以:

  1. 设置断点以暂停执行。
  2. 该对象必须在执行范围内。
  3. 将鼠标指针移到对象或变量上方。
  4. 将出现黄色工具提示。
  5. 将鼠标移动到工具提示上方。
  6. 单击指向上下两个箭头的两个小箭头。
  7. 一个上下文菜单会弹出。
  8. 选择“打印描述”,它将执行一个[对象描述]。
  9. 描述将显示在控制台输出中。

我认为这有点隐蔽和繁琐......


在我的Xcode中,“打印描述”不起作用,我该如何启用它? - Kirtikumar A.
@kirtiavaiya 应用程序必须暂停,您的变量需要在当前范围内才能打印。此外,您不能直接打印“self.variable”,但是您可以使用Andriy的解决方案来打印_<variable's name>。例如:对于self.btnHello,在控制台中写入“po _btnHello”(仅当您没有更改getter方法的名称时才有效)。 - LightMan
@LightMan 是的,就像你说的那样,但它仍然没有起作用。 - Kirtikumar A.

11
你的困惑源于“声明的属性不一定与实例变量同名”的事实。
表达式
indexPath.row

等同于

[indexPath row]

以及分配任务

delegate.myData = [myData objectAtIndex:indexPath.row];

等同于

[delegate setMyData:[myData objectAtIndex:[indexPath row]]];

假设合成属性的命名标准。

此外,delegate 可能被声明为类型 id<SomeProtocol>,即编译器在那一点上无法提供有关 delegate 的实际类型信息,调试器依赖于编译时提供的信息。由于 id 是一个通用类型,因此没有关于 delegate 中实例变量的编译时信息。

这些是您看不到 myDatarow 作为变量的原因。

如果您想检查发送 -row-myData 的结果,可以使用命令 ppo

p (NSInteger)[indexPath row]
po [delegate myData]

或者使用表达式窗口(例如,如果您知道您的delegate的实际类型是MyClass *,您可以添加一个表达式(MyClass *)delegate,或右键单击delegate,选择查看值为...并输入delegate的实际类型(例如MyClass *)。

话虽如此,我同意调试器可能会更有帮助:

  • 可以有一个选项告诉调试器窗口使用运行时类型信息而不是编译时信息。它会减慢调试器的速度,但会提供有用的信息;

  • 声明的属性可以显示在名为属性的组中,并允许(可选)直接在调试器窗口中进行检查。这也会因需要发送消息/执行方法以获取信息而减慢调试器的速度,但也会提供有用的信息。


7
您可以在运行时将值打印到控制台窗口。以下是步骤:
  1. 为想要获取值的断点设置断点
  2. 现在逐步执行调试。
  3. 将光标放在要在运行时检查其值的变量/委托上。
  4. 现在会显示变量/委托的说明
  5. 单击“i”会显示详细说明
  6. 这也会将详细信息打印到控制台窗口。

在控制台窗口上打印详细信息的屏幕截图


1
这在 Swift 上可行吗?我是 Swift 新手,无法像在 Objective-C 中那样查看对象的值。 - umairhhhs
1
@umairhhhs 这篇文章仅适用于Objective-C。 - Jayprakash Dubey
1
我在想为什么这个功能不在Swift编辑器中,因为那是非常有帮助和节省时间的特性。 - umairhhhs

1

这有点复杂。这些对象是自定义类或结构体,而在Xcode中查看它们并不像其他开发环境那样容易。

如果我是你,我会使用NSLog记录想要查看的值,并加上一些描述。

i.e:

NSLog(@"Description of object & time: %i", indexPath.row);

11
是的,NSLog是一种可能性,但不是舒适的调试替代品。我很惊讶没有办法显示所需的值,这应该是开发环境基本功能之一。 - Manni
2
XCode最令人恼火的事情。可悲。 - ryan0

1

尝试运行 -> 显示 -> 表达式

输入数组的名称或你要查找的任何内容。


谢谢!我在表达式窗口中输入了"indexPath.row"和"delegate.myData",但每次在"Summary"列中都会出现"out of scope" :-( - Manni
没问题,我之前也遇到过同样的问题,直到我找到了解决方案 ;) - tbone
1
在设置数组(或其他内容)后立即设置断点,您应该能够在“表达式”中找到值。祝好运。 - tbone

0
在代码编辑器下方的调试区域中,右键单击,并选择“添加表达式...”上下文菜单项。在此处输入变量,例如delegate.myData,就这样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接