20171122
Objective-C中遇到一个一时想不通的现象:条件编译
#if !TARGET_IPHONE_SIMULATOR
......
#else
......
#endif
无法生效,即#if
和#endif
中的代码在iPhone模拟器上居然会被编译。后来才想明白,原来是我没有引用Apple SDK usr/include
路径中的TargetConditionals.h
头文件,因为TARGET_IPHONE_SIMULATOR
宏是在这个文件中被定义的。在未定义的情况下,#if !TARGET_IPHONE_SIMULATOR
等价于#if !0
即为#if 1
,永远为真,所以任何情况下都会被编译。
正确的写法如下:
#import <TargetConditionals.h>
#if !TARGET_IPHONE_SIMULATOR
......
......
#else
......
......
#endif /** TARGET_IPHONE_SIMULATOR */
当然,如果你在用到TARGET_IPHONE_SIMULATOR
宏时,已经在其他地方包含过TargetConditionals.h
,或间接包含这个文件(比如常见的是包含了UIKit.h
或Foundation.h
),则不会出现此问题。
这篇记录的意义是,当遇到类似的怪异现象时,要有怀疑宏常量是否被定义的意识。
环境: Xcode 9.1;
项目: Swift 3.2 和 Objective-C混编;
PS: 在Swift中应该不存在这样的问题,一直如下使用条件编译,暂未遇到问题:
#if arch(i386) || arch(x86_64)
// i386和x86_64 架构下才会编译, 既一般的intel处理器机器;
#else
// 在iOS开发中, 此处else一般可以限定为armv7 arm64架构, 即一般的iPhone、iPad、iWatch、AppleTV等真机
#endif