Objective-C @available ガードにさらに条件を AND する 質問する

Objective-C @available ガードにさらに条件を AND する 質問する

Objective-Cには@available表現XCode 9+ / LLVM 5+ では、特定の OS バージョン以上に対してコード ブロックをガードできるため、その OS バージョンでのみ使用可能な API を使用する場合に、ガードされていない可用性の警告が発行されなくなります。

問題は、この可用性ガードは、 の条件で唯一の式である場合にのみ機能することですif。他のコンテキストで使用すると、警告が表示されます。

@available does not guard availability here; use if (@available) instead

たとえば、可用性チェックを他の条件と AND で結合しようとしても機能しませんif

if (@available(iOS 11.0, *) && some_condition) {
  // code to run when on iOS 11+ and some_condition is true
} else {
  // code to run when on older iOS or some_condition is false
}

ifブロック内または still 内で iOS 11 API を使用するコードは、some_conditionそれらのコード部分に iOS 11 以降でのみアクセスできることが保証されているにもかかわらず、保護されていない可用性の警告を生成します。

これを 2 つのネストされた に変更することもできますifが、その場合、elseコードを複製する必要があり、これは良くありません (特にコードが大量にある場合)。

if (@available(iOS 11.0, *)) {
  if (some_condition) {
    // code to run when on iOS 11+ and some_condition is true
  } else {
    // code to run when on older iOS or some_condition is false
  }
} else {
  // code to run when on older iOS or some_condition is false
}

elseブロック コードを匿名関数にリファクタリングすることで重複を回避できますが、elseの前にブロックを定義する必要がありif、コード フローがわかりにくくなります。

void (^elseBlock)(void) = ^{
  // code to run when on older iOS or some_condition is false
};

if (@available(iOS 11.0, *)) {
  if (some_condition) {
    // code to run when on iOS 11+ and some_condition is true
  } else {
    elseBlock();
  }
} else {
  elseBlock();
}

誰かもっと良い解決策を思いつくでしょうか?

ベストアンサー1

関数の途中に複雑な条件コードがあり、フローが複雑になる場合は、いつものように、それを別の関数に持ち上げます。

- (void)handleThing {
    if (@available(iOS 11.0, *)) {
        if (some_condition) {
            // code to run when on iOS 11+ and some_condition is true
            return;
        }
    }

  // code to run when on older iOS or some_condition is false
}

または、チェックを汎用コードに昇格します (Josh Caswell のコードを参照してください。これは私が最初に書いたものよりも優れています)。

おすすめ記事