否定 Objective-C 的 @available 关键字
Negating Objective-C's @available keyword
我想 运行 仅当当前设备的 iOS 版本低于指定的特定版本时 运行 一段代码 。 Apple 给出的代码示例如下所示:
if (@available(iOS 10.0, *)) {
// iOS 10.0 and above
} else {
// below 10.0
}
但是,在某些情况下,只有当当前 iOS 版本低于特定版本时,人们才想 运行 编写代码。我假设以下代码可以工作:
if (!@available(iOS 10.0, *)) {
// below 10.0
}
但是这似乎不起作用,我从 Xcode 收到以下警告:
@available does not guard availability here; use if (@available) instead
Here 是添加了我所看到的诊断的 LLVM 提交。
该问题有两种可能的后备方案:
- 使用
if-else
变体而不向 if
块添加任何代码(不是很优雅)。
- 继续使用旧方法,例如
-[NSProcessInfo isOperatingSystemAtLeastVersion:]
。
是否有另一种使用我所缺少的 @available
的预期方法?
You can define your own custom macros that you can use throughout your application. Example:-
#define isIOS11() ([[UIDevice currentDevice].systemVersion doubleValue]>= 11.0 && [[UIDevice currentDevice].systemVersion doubleValue] < 12.0)
或
#define SinceIOS9_2 ([[UIDevice currentDevice].systemVersion doubleValue]>= 4.2 && [[UIDevice currentDevice].systemVersion doubleValue] < 9.2)
像下面这样使用它:-
if (isIOS11()) {
// Do something for iOS 11
} else {
// Do something iOS Versions below 11.0
}
如果这对你有用,请告诉我。
@available
的想法是您想使用仅在某些系统上可用的 API。对于其他系统,该功能要么在您的应用程序中缺失,要么您提供了替代功能。在不需要特定 OS 版本以外的任何代码的情况下,正确的使用方法是
if (@available(iOS 10.0, *)) {
// Happens automatically on on iOS 10 and beyond
} else {
someOtherCode();
}
原因是编译器有时必须对 @available
保护的代码执行一些额外的魔法,因此它需要清楚地识别这种情况。所以实际上它明确搜索
if (@available(...)) {
只允许空格和换行符的变化。是的,您可能会怀疑单个非 (!
) 实际上一点也不复杂,但是您会在哪里划清界限呢?怎么样:
if ((todayIsTuesday() && @available(iOS 9.0, *))
|| (self.theWeatherIsNice && !@available(iOS 11.0, *)) {
因此只允许一个简单的语句,它只会强制编译器将代码分成两部分,并且总是只有一个部分 运行 肯定:一个用于列出的 OSes 和一个对于其余的。当然,"the rest"可以再细分,else if
是允许的。只有 else 部分如果缺失可以自动生成,所以当你这样写时:
if (@available(...)) {
someCode();
} // There is no else
编译器也很高兴,因为那是一样的
if (@available(...)) {
someCode();
} else {
// Nothing to do here
}
if (@available ...) {
...
} else {
...
}
是唯一允许的形式。它必须像那样,因为不同的规则适用于 if 部分和 else 部分。在 if 部分,您可以调用一个 SDK 中可用的方法,在 else 部分,它是来自另一个 SDK 的方法。同一个调用在一个分支中可能是合法的而在另一个分支中是非法的,或者在一个分支中被弃用而在另一个分支中不被推荐。
我想 运行 仅当当前设备的 iOS 版本低于指定的特定版本时 运行 一段代码
if (@available(iOS 10.0, *)) {
// iOS 10.0 and above
} else {
// below 10.0
}
但是,在某些情况下,只有当当前 iOS 版本低于特定版本时,人们才想 运行 编写代码。我假设以下代码可以工作:
if (!@available(iOS 10.0, *)) {
// below 10.0
}
但是这似乎不起作用,我从 Xcode 收到以下警告:
@available does not guard availability here; use if (@available) instead
Here 是添加了我所看到的诊断的 LLVM 提交。
该问题有两种可能的后备方案:
- 使用
if-else
变体而不向if
块添加任何代码(不是很优雅)。 - 继续使用旧方法,例如
-[NSProcessInfo isOperatingSystemAtLeastVersion:]
。
是否有另一种使用我所缺少的 @available
的预期方法?
You can define your own custom macros that you can use throughout your application. Example:-
#define isIOS11() ([[UIDevice currentDevice].systemVersion doubleValue]>= 11.0 && [[UIDevice currentDevice].systemVersion doubleValue] < 12.0)
或
#define SinceIOS9_2 ([[UIDevice currentDevice].systemVersion doubleValue]>= 4.2 && [[UIDevice currentDevice].systemVersion doubleValue] < 9.2)
像下面这样使用它:-
if (isIOS11()) {
// Do something for iOS 11
} else {
// Do something iOS Versions below 11.0
}
如果这对你有用,请告诉我。
@available
的想法是您想使用仅在某些系统上可用的 API。对于其他系统,该功能要么在您的应用程序中缺失,要么您提供了替代功能。在不需要特定 OS 版本以外的任何代码的情况下,正确的使用方法是
if (@available(iOS 10.0, *)) {
// Happens automatically on on iOS 10 and beyond
} else {
someOtherCode();
}
原因是编译器有时必须对 @available
保护的代码执行一些额外的魔法,因此它需要清楚地识别这种情况。所以实际上它明确搜索
if (@available(...)) {
只允许空格和换行符的变化。是的,您可能会怀疑单个非 (!
) 实际上一点也不复杂,但是您会在哪里划清界限呢?怎么样:
if ((todayIsTuesday() && @available(iOS 9.0, *))
|| (self.theWeatherIsNice && !@available(iOS 11.0, *)) {
因此只允许一个简单的语句,它只会强制编译器将代码分成两部分,并且总是只有一个部分 运行 肯定:一个用于列出的 OSes 和一个对于其余的。当然,"the rest"可以再细分,else if
是允许的。只有 else 部分如果缺失可以自动生成,所以当你这样写时:
if (@available(...)) {
someCode();
} // There is no else
编译器也很高兴,因为那是一样的
if (@available(...)) {
someCode();
} else {
// Nothing to do here
}
if (@available ...) {
...
} else {
...
}
是唯一允许的形式。它必须像那样,因为不同的规则适用于 if 部分和 else 部分。在 if 部分,您可以调用一个 SDK 中可用的方法,在 else 部分,它是来自另一个 SDK 的方法。同一个调用在一个分支中可能是合法的而在另一个分支中是非法的,或者在一个分支中被弃用而在另一个分支中不被推荐。