Swift条件编译&x27;使用objective-c中定义的宏时,无法正常工作
我在objective-c头文件中定义了一个简单的宏,并通过项目桥接头文件将该头文件导入Swift。我可以在Swift中将此宏用作常量,但当我使用它进行条件编译时,它无法正常工作 我在Xcode 10.2.1中创建了一个简单的项目,并添加了一些代码来重现它。 在ViewController.h中Swift条件编译&x27;使用objective-c中定义的宏时,无法正常工作,objective-c,swift,Objective C,Swift,我在objective-c头文件中定义了一个简单的宏,并通过项目桥接头文件将该头文件导入Swift。我可以在Swift中将此宏用作常量,但当我使用它进行条件编译时,它无法正常工作 我在Xcode 10.2.1中创建了一个简单的项目,并添加了一些代码来重现它。 在ViewController.h中 #定义测试标志1 @界面ViewController:UIViewController @结束 在ViewController.m中 #import "testMacro-Swift.h" - (v
#定义测试标志1
@界面ViewController:UIViewController
@结束
在ViewController.m中
#import "testMacro-Swift.h"
- (void)viewDidLoad {
[super viewDidLoad];
SwiftClass *s = [[SwiftClass alloc] init];
[s printMSG];
#if TEST_FLAG
NSLog(@"Objc works.");
#endif
}
在testMacro桥接Header.h中
#import "ViewController.h"
快捷文件
@objc class SwiftClass: NSObject {
@objc func printMSG() {
print("Macro \(TEST_FLAG)")
#if TEST_FLAG
print("compiled XXXxXXXXX")
#endif
}
}
控制台输出
Macro 1
2019-07-03 14:38:07.370231-0700 testMacro[71724:11911063] Objc works.
我希望编译后的XXXxXXXXX会在宏1之后打印,但事实并非如此
我很好奇为什么会发生这种情况。
我的项目混合了objc和swift。我不想在swift中声明相同的标志。基于这篇苹果文章,简单C(和Objective-C)宏作为全局常量导入swift。这可以通过生产线的输出来证明
print("Macro \(TEST_FLAG)")
片段
#if TEST_FLAG
print("compiled XXXxXXXXX")
#endif
使用不同的测试标志
,这是一个Swift预处理器标志。您可以在生成设置->活动编译条件下将其定义为TEST\u FLAG
,或者在生成设置->其他Swift标志下将其定义为-DTEST\u FLAG
以上解释了为什么会发生这种情况。我想不出一个简单的方法来避免在Xcode中分别为Objective-C和Swift预处理器定义相同的标志。如果您只想根据TEST\u标志
控制是否执行某些Swift代码,可以执行以下操作:
if TEST_FLAG != 0 {
print("compiled XXXxXXXXX")
}
但是,如果您想要控制代码的编译,那么您可能必须对Objective-C和Swift使用单独的TEST_标志
s,并确保它们一致。为了帮助它们保持一致,您可以在其他C标志
中设置Objective-C代码使用的测试标志
,这允许您为不同的SDK、体系结构和构建类型(发布/调试)定义不同的标志。活动编译条件允许同样的灵活性
促进(目标-)C和Swift编译器标志之间一致性的另一个技巧是创建一个新的用户定义的生成设置:单击“生成设置”下搜索框左侧的+
比方说,将其称为COMMON\u TEST\u FLAG
,并将其值设置为TEST\u FLAG
。然后将-D$(公共测试标志)
添加到其他C标志和其他Swift标志。现在,当您构建代码时,TEST\u标志
将在目标中的Objective-C和Swift代码中定义。如果不想定义它,只需将COMMON\u TEST\u FLAG
的值更改为其他值即可。不过,有几件事需要注意:
- 不能将
设为空:这将导致另一个 标记为-D,导致生成错误李>COMMON\u TEST\u标志
- 确保
COMMON\u TEST\u标志的值与 在别处定义的宏
n
唯一标志,有2^n可能的值集,因此,
2^n`可能的构建。你必须测试每一个吗?也许,也许不是,但即使只是对测试内容进行推理也不容易#define max(a,b)((a)<(b)?(b):(a))
)。虽然这是非常罕见的
一种更好的方法(在Swift和Objective C中)是创建一个记录器,该记录器在调试和发布版本之间使用不同的配置进行初始化。您的
viewDidLoad
方法不应该关心是否设置了TEST\u标志。视图控制器应该控制视图,而不是决定应该记录哪些内容。它应该只调用记录器发送它想要发送的任何日志消息,并让记录器决定如何记录这些消息(到输出流、文件、内存循环缓冲区、数据库、流到分析API、忽略它们等)我确实在桥接头中导入objc文件。您可以看到print(“Macro\(TEST\u FLAG)”)
运行,并打印正确的TEST\u FLAG,但这不是条件编译,这就是问题所在。对不起,您是对的,@matt。我读这个问题太匆忙了。修改了答案。