因为实习接触的项目,需将对不支持模拟器的代码用宏“干掉”,大部分用常见的宏处理就可以了。但有一小部分还是不行,于是这个简单的处理就交给了笔者。

C++ 对不同的平台的宏处理

了解问题后,研究了一下。在iOS中对模拟器的判断,笔者发现不同的语言有不同的使用方法,比如如果在oc的 .m 或者与 C++ 混编的 .mm 文件里,我们可以直接引用 TARGET_IPHONE_SIMULATOR 这个进行宏的预处理。将不能执行在模拟器里的方法处理一下。如果在 C++ 的文件里呢?上面方法就不适用了,为什么呢?原因在于 .m / .mm 文件里是 OC 的语法,TARGET_IPHONE_SIMULATOR 宏可以直接找到 targetconditionals.h 这个头文件。里面的定义可以看出来 TARGET_IPHONE_SIMULATOR 是判断模拟器的唯一区别的宏。而在 C++ 里面不能直接找到其对应的 targetconditionals.h,需要手动引入。这样就解决了混编项目里 C++ 中的函数或方法,在运行模拟器中报错的问题。如果想用 C++ 进行跨平台的处理,具体需要看看 stack overflow 上看看 这个回答,这里就不过多阐述了。 How to detect reliably Mac OS X, iOS, Linux, Windows in C preprocessor?

Swift 的处理呢?

如果是swift呢?在 stack overflow 也有讨论,给的方法很多。如使用

#if (arch(i386) || arch(x86_64)) && os(iOS)
    ...
#endif

但是这样的方法不是很好,stack overflow 有一个得票不高但是是 Apple 官方推荐的方法。在这里 Detect if app is being built for device or simulator in Swift 有大神给出了,官方最新推出的解决方案 #if targetEnvironment(simulator)

但这个方案只对 swift 4.1 和 Xcode 9.3 以上的有效。之前的需要按照上述的答案,进行自定义的宏处理。

如有不足,希望大家多多批评。

参考文档

How to detect reliably Mac OS X, iOS, Linux, Windows in C preprocessor?

Detect if app is being built for device or simulator in Swift