首页 > 解决方案 > LLDB 如何在 OC 中使用文件定义的宏

问题描述

我已经尝试了多种变体,但似乎都不起作用。有任何想法吗?

ViewController.m

UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(100, 200, 300, 300)];
view1.backgroundColor = [UIColor redColor];
[self.view addSubview:view1];

另一个文件UIView+Frame.h 我定义了一个颜色宏

#define RGBACOLOR(r,g,b,a) [UIColor colorWithRGB:r Green:g Blue:b Alpha:a]

实际操作 程序执行的[self.view addSubview: view1];时候我打算用LLDB用定义的宏来修改颜色,但是提示错误不知道怎么修改。错误结果如下

(lldb) e view1.backgroundColor = (UIColor *)RGBACOLOR(0,0,0,1)
error: use of undeclared identifier 'RGBACOLOR'
(lldb) 

标签: ioslldb

解决方案


调试信息传统上不能很好地支持宏。DWARF 标准(这是 macOS 和其他 Unixen 上最常见的标准)有一种存储信息的方法,但它非常冗长,很少有工具链支持它。所以调试器没有自然的方式来了解定义。

如果您想在调试表达式中使用少量相当独立的宏,您可以将它们放在一个 .h 文件中,并将该文件设置为 lldb 的“表达式前缀”。这将包含在您随后运行的每个表达式的源代码中。通过以下方式执行此操作:

(lldb) settings set target.expr-prefix ~/my-common-defines.h

在这里你不能太雄心勃勃(例如#include <unistd.h>不会工作)。问题是大多数系统头文件都受一组其他#defines 的限制。lldb 不知道它们的值是什么,因此在某些时候预处理 expr-prefix 会失败。

或者,clang 也有一个称为“模块”的概念,它试图使某些包中的头文件集合更易于重复编译。它实际上捕获了一些会导致 expr-prefix 解析失败的信息。因此,如果您要访问的宏位于 Clang 模块中内置的一组标头中,那么您可以将该模块导入 lldb 的表达式上下文,这将使模块中的定义也可用。例如:

(lldb) expr -l objc -- @import Foundation

将使所有 Foundation 宏定义可用。

同样,如果您的标题是模块化的(此页面深入了解这意味着什么:

https://clang.llvm.org/docs/Modules.html

) 然后您可以导入您创建的模块,其定义将可用于表达式解析器。


推荐阅读