否定Objective-C的@available关键字

时间:2017-09-24 09:16:53

标签: ios objective-c ios11 xcode9 availability

我想仅在当前设备的iOS版本低于指定here的特定版本时才运行一段代码。 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提交,它添加了我看到的诊断。

该问题有两种可能的后备:

  1. 使用if-else变体而不向if块添加任何代码(不是很优雅)。
  2. 继续使用-[NSProcessInfo isOperatingSystemAtLeastVersion:]等旧方法。
  3. 是否还有另一种使用我@available的方法?

3 个答案:

答案 0 :(得分:4)

@available的想法是您要使用仅在某些系统上可用的API。对于其他系统,您的应用程序中缺少该功能,或者您提供了替代功能。在某些情况下,仅在下面的操作系统版本中不需要任何代码的情况下,正确的使用方式是

if (@available(iOS 10.0, *)) {
    // Happens automatically on on iOS 10 and beyond
} else {
    someOtherCode();
}

这样做的原因是,编译器有时不得不对@available保护的代码执行一些额外的魔术,因此,在这种情况下,它需要清楚地识别。因此,实际上它明确搜索

if (@available(...)) {

,仅允许空格和换行符变化。是的,您可能会怀疑单个not(!)确实很复杂,但是您会在哪里划清界限?怎么样:

if ((todayIsTuesday() && @available(iOS 9.0, *)) 
    || (self.theWeatherIsNice && !@available(iOS 11.0, *)) {

因此,只允许执行一条简单的语句,该语句仅强制编译器将代码分为两部分,并且始终确保只有一部分可以运行:一个用于列出的OS,另一个用于其余的OS。当然,然后可以再次细分“其余”,允许else if。如果缺少,则只有else节可以自动生成,因此在编写时:

if (@available(...)) {
    someCode();
} // There is no else

编译器也很高兴,因为它与

相同
if (@available(...)) {
     someCode();
} else {
    // Nothing to do here
}

答案 1 :(得分:1)

  

您可以定义自己的自定义宏,以便在整个应用程序中使用。例如: -

#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
}

如果这对你有用,请告诉我。

答案 2 :(得分:0)

if (@available ...) {
   ...
} else {
   ...
}

是唯一允许的形式。必须这样,因为if-部分和else-部分应用了不同的规则。在if部分中,您可以调用一个SDK中可用的方法,在其余部分中,它是另一SDK中的方法。同一呼叫在一个分支机构中可能是合法的,而在另一个分支机构中则是非法的,或者在一个分支机构而不是另一个分支机构中已弃用。