Swift 提供了一个名为
os
的特殊预处理器指令来检查您正在运行的操作系统:
struct A {
#if os(iOS)
let a: AvailableOnIOS
#elseif os(tvOS)
let a: AvailableOnTVOS
#endif
}
我很感兴趣 Objective-C 中是否有类似的东西可以使用
@interface A: NSObject
#if os(iOS)
@property (nonatomic, strong) AvailableOnIOS* a;
#elseif os(tvOS)
@property (nonatomic, strong) AvailableOnTVOS* a;
#endif
@end
您问题的答案是:
@interface A : NSObject
#if TARGET_OS_IOS
@property(nonatomic) AvailableOnIOS * a;
#elsif TARGET_OS_TV
@property(nonatomic) AvailableOnTVOS * a;
#endif
@end
请勿使用
TARGET_OS_IPHONE
,因为它包括所有嵌入式系统。正如 TARGET_OS_MAC
包括所有 Apple 系统一样。
引用 Apple 的
TargetConditionals.h
标题:
+--------------------------------------------------------------------------------------+
| TARGET_OS_MAC |
| +-----+ +------------------------------------------------------------+ +-----------+ |
| | | | TARGET_OS_IPHONE | | | |
| | | | +-----------------+ +----+ +-------+ +--------+ +--------+ | | | |
| | | | | IOS | | | | | | | | | | | | |
| | OSX | | | +-------------+ | | TV | | WATCH | | BRIDGE | | VISION | | | DRIVERKIT | |
| | | | | | MACCATALYST | | | | | | | | | | | | | |
| | | | | +-------------+ | | | | | | | | | | | | |
| | | | +-----------------+ +----+ +-------+ +--------+ +--------+ | | | |
| +-----+ +------------------------------------------------------------+ +-----------+ |
+--------------------------------------------------------------------------------------+
MAC之所以包罗万象,是因为其他所有操作系统其实都是对macOS系统进行了剥离,所以MAC就成了“苹果平台”的代名词。此级别的其他平台有:
TARGET_OS_WIN32
TARGET_OS_WINDOWS
TARGET_OS_UNIX
TARGET_OS_LINUX
TARGET_OS_MAC
iPhone OS(今天称为 iOS)是 macOS 的第一个精简版本,所有其他系统都是 iPhone OS 的修改版本,这就是为什么
TARGET_OS_MAC
下面的层被分为:
TARGET_OS_OSX
TARGET_OS_IPHONE
TARGET_OS_SIMULATOR
TARGET_OS_DRIVERKIT
并且
TARGET_OS_IPHONE
有以下子层:
TARGET_OS_IOS
TARGET_OS_TV
TARGET_OS_WATCH
TARGET_OS_VISION
TARGET_OS_BRIDGE
TARGET_OS_IOS
下面还有最后一个子层,那就是 TARGET_OS_MACCATALYST
。 “Mac Catalyst”本身并不是真正的平台,而是通过桌面 API 功能扩展的 iOS API 的子集。这种添加的桌面功能是 iPadOS 与 iPhone 上的 iOS 的不同之处:它们都是 iOS,但 iPadOS 具有 iPhone 上的标准 iOS 所没有的附加功能。整个 Catalyst API 向后移植到 macOS,因此仅限于 Catalyst API 的应用程序可以在 iPad 和 Mac 上运行,无需进一步修改。请注意,大多数普通 iPhone 应用程序也可以在 Mac 上运行,但只能在 ARM Mac 上运行,而 Catalyst 应用程序也可以在 Intel Mac 上运行,因为 Catalyst API 也可用于 x86_64 系统。
这张图中缺少的是
TARGET_OS_SIMULATOR
,当代码在模拟器中运行时它总是被设置;不管什么模拟器。例如。如果您希望一段代码仅在 iOS 模拟器中运行时使用,而不是在其他模拟器(tvOS、watchOS)中运行,那么您可以使用
#if TARGET_OS_SIMULATOR && TARGET_OS_IOS
#endif
请注意,此代码也不会在真正的 iOS 设备上运行。
还值得注意的是不同目标 CPU 的定义:
TARGET_CPU_PPC
TARGET_CPU_PPC64
TARGET_CPU_68K
TARGET_CPU_X86
TARGET_CPU_X86_64
TARGET_CPU_ARM
TARGET_CPU_ARM64
TARGET_CPU_MIPS
TARGET_CPU_SPARC
TARGET_CPU_ALPHA
以及以下属性的定义:
TARGET_RT_LITTLE_ENDIAN
:生成的代码对整数使用小端格式TARGET_RT_BIG_ENDIAN
:生成的代码对整数使用大端格式TARGET_RT_64_BIT
:生成的代码使用 64 位指针TARGET_RT_MAC_MACHO
:TARGET_OS_MAC
为真,并且使用 Mach-O/dlyd 运行时所有其他目标条件均已弃用或在实践中几乎无用。