【发布时间】:2020-07-31 02:36:36
【问题描述】:
尝试在AppDelegate.m 文件中添加块
#if compiler(>=5.0)
if (@available(iOS 13.0, *)) {
// do something...
}
#endif
显示的错误是:
未定义类似函数的宏“编译器”
【问题讨论】:
标签: ios swift objective-c xcode preprocessor
尝试在AppDelegate.m 文件中添加块
#if compiler(>=5.0)
if (@available(iOS 13.0, *)) {
// do something...
}
#endif
显示的错误是:
未定义类似函数的宏“编译器”
【问题讨论】:
标签: ios swift objective-c xcode preprocessor
以下是 Swift 编译时指令:
#if compiler(>=5.0)
...
#endif
在 Objective-C 文件AppDelegate.m 中使用它是没有意义的。在 Objective-C 源代码中,会导致“Function-like macro 'compiler' is not defined”错误。
因此,如果您想要对 iOS 13 进行运行时检查,只需删除 #if,例如:
if (@available(iOS 13.0, *)) {
...
}
见Marking API Availability in Objective-C。
一些观察结果(假设您使用 swift 标记了此内容):
在 Swift 中,编译时模式是:
#if swift(>=5.0)
...
#endif
或者
#if compiler(>=5.0)
...
#endif
这种模式通常只在编写第三方库时使用,您需要为使用早期版本的 Swift 编译库的开发人员提供向后支持。
见The Swift Programming Language: Compiler Control Statements
以下是 OS 版本的 Objective-C 运行时检查:
if (@available(iOS 13.0, *)) {
// do something...
}
等效的 Swift 模式是:
if #available(iOS 13.0, *) {
...
}
这些在编写针对多个 iOS 版本的代码时很有用,但您希望使用 iOS 13+ API 有条件地运行代码。
为了混淆,Swift 确实有一个 @available 构造,但它用于将类、扩展或方法标记为仅适用于运行特定操作系统版本的设备,但不与 @ 一起使用987654333@测试。例如。假设您正在定义一些仅适用于 iOS 13 及更高版本的函数:
@available(iOS 13.0, *)
func someMethod() {
...
}
这是 compile-time 构造是告诉编译器不要在此函数中抱怨 iOS 13 API,如果您的应用碰巧支持早期的 iOS 版本。您实际上是在告诉编译器“嘿,我知道其中包含仅适用于 iOS 13 及更高版本的代码,但不要担心,因为我只会在相关设备运行 iOS 13 或更高版本时调用它。 ”
【讨论】:
您在代码示例中做错了很多事情:
#if 是一个预处理器宏。您只能在任何范围之外使用它,就像import 语句一样。如果您以应有的方式使用它,那么您不能在那里使用if 语句。
@available 不能在 if 语句中使用。它只能用于表示特定类/结构/函数是否可用于所述操作系统版本及更高版本,但不能用于表示代码片段。为此,请改用它:
if #available(iOS 13.0, *) {
// Do something.
}
【讨论】:
如果要具体查看 Swift 编译器版本,可以使用#if swift。要在运行时检查iOS 版本,您需要使用#available,如果用于标记仅在所述版本上可用的类型/功能,则使用@ 版本。
#if swift(>=5.0)
if #available(iOS 13,*) {
//do something
}
#endif
【讨论】: