19

在 Objective-C 中,我有时会在 LLDB 中设置观察点,让我知道实例变量何时发生了变化。我也可以使用 Swift 属性来执行此操作吗?

现在,我能做到这一点的唯一方法是:

  • 将 didSet 处理程序添加到属性并在内部设置断点(但这需要停止程序并重新编译,这会违背目的)
  • 添加一个符号断点,[setPropertyName:]但这仅在该类恰好支持Objective-C桥接时才有效

我还有其他选择吗?

4

2 回答 2

29

答案比我想象的要简单得多。最简单的方法是简单地在属性声明上添加一个断点。每当读取或写入属性时,调试器都会中断。

如果像我一样,您只想在属性更改时中断并忽略获取,请在属性声明上设置断点,然后进入 LLDB 控制台并键入“br list”以查看所有断点的列表:

(lldb) br list
Current breakpoints:
1: file = '/Users/testuser/Desktop/TestFoo/Test.swift', line = 12, locations = 3, resolved = 3, hit count = 1

  1.1: where = TestFoo`TestFoo.Test.x.getter : Swift.Int + 12 at Test.swift:12, address = 0x00000001084cfefc, resolved, hit count = 1 
  1.2: where = TestFoo`TestFoo.Test.x.setter : Swift.Int + 16 at Test.swift:12, address = 0x00000001084cff80, resolved, hit count = 0 
  1.3: where = TestFoo`TestFoo.Test.x.materializeForSet : Swift.Int + 16 at Test.swift:12, address = 0x00000001084d00f0, resolved, hit count = 0 

如您所见,有一个主断点“1”和三个子断点。禁用 getter 的子断点:

(lldb) br disable 1.1
1 breakpoints disabled.

一切就绪。只有当该属性被修改时,调试器才会中断。

于 2015-01-23T19:14:27.930 回答
7

在 XCode(8.2 Swift 3.0)上,通常在 swift 属性上设置断点,然后运行您的应用程序。应用程序运行后转到断点面板,您可以将断点扩展为多个断点:

在此处输入图像描述

默认情况下全部选中,然后您可以禁用不需要的那些。注意:我发现当你第一次添加断点时,它不会扩展,直到你运行应用程序。

您可以尝试的另一种方法是使用 lldb 添加它们。首先在类实例中的某处添加断点,例如 viewDidLoad ext。p self 并记下实例的内存地址。

然后像这样添加断点,其中 0x0f0f0f0f0f0f 是对象的内存地址。

break set -F '-[MyClass setMyProperty:]' -c '$rdi == 0x0f0f0f0f0f0f'
于 2017-03-28T23:13:48.857 回答