我在Objective-C头文件中定义了一个简单的宏,然后通过项目桥接头将该头文件导入Swift。我可以在Swift中将此宏用作常量,但是当我使用它进行条件编译时,它无法正常工作。
我在Xcode 10.2.1中创建了一个简单的项目,并添加了一些代码来重现它。在ViewController.h中
#define TEST_FLAG 1
@interface ViewController : UIViewController
@end
在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-Bridging-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.
我希望compiled XXXxXXXXX
在之后打印Macro 1
,但不会。
我很好奇为什么会这样。我的项目混合了objc和swift。我不想迅速声明相同的标志。
根据这篇Apple文章,https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/using_imported_c_macros_in_swift,简单的C(和Objective-C)宏作为全局常量导入了Swift。您的行的输出证明了这一点
print("Macro \(TEST_FLAG)")
片段
#if TEST_FLAG
print("compiled XXXxXXXXX")
#endif
使用different TEST_FLAG
,这是Swift预处理器标志。您可以在“构建设置”->“活动编译条件”TEST_FLAG
下或“构建设置”->“其他Swift标志”下定义它-DTEST_FLAG
。
上面解释了为什么会这样。我想不出一种简单的方法来避免为Xcode中的Objective-C和Swift预处理器分别定义相同的标志。如果您只想控制是否基于来执行某些Swift代码,则TEST_FLAG
可以执行以下操作:
if TEST_FLAG != 0 {
print("compiled XXXxXXXXX")
}
但是,如果要控制代码的编译,则可能必须TEST_FLAG
对Objective-C和Swift使用单独的,并确保它们是一致的。为了帮助使它们一致,可以在中设置TEST_FLAG
Objective-C代码所使用的代码Other C Flags
,该代码允许您为不同的SDK,体系结构和内部版本(发布/调试)定义不同的标志。主动编译条件允许相同的灵活性。
促进(Objective-)C和Swift编译器标志一致的另一个技巧是创建一个新的用户定义的构建设置:单击“+
构建设置”下搜索框左侧。
说,调用它COMMON_TEST_FLAG
并将其值设置为TEST_FLAG
。然后添加-D$(COMMON_TEST_FLAG)
到其他C标志和其他Swift标志。现在,在构建代码时,TEST_FLAG
将在目标内的Objective-C和Swift代码中定义代码。如果您不想定义它,只需将其值更改为其他值COMMON_TEST_FLAG
即可。不过,需要注意以下几点:
COMMON_TEST_FLAG
空:这将导致其他标志仅为-D,从而导致生成错误。COMMON_TEST_FLAG
与其他地方定义的宏不冲突。本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句