Objective-C имеет выражение @available
в XCode 9+/LLVM 5+, которое позволяет защитить блок кода до по крайней мере, для определенной версии ОС, чтобы она не выдавала предупреждения о неохраняемой доступности, если вы используете API, которые доступны только для этой версии ОС.
Проблема заключается в том, что эта проверка доступности заключается в том, что она работает только в том случае, если она является единственным выражением в состоянии if
. Если вы используете его в любом другом контексте, вы получите предупреждение:
@available does not guard availability here; use if (@available) instead
Так, например, это не работает, если вы пытаетесь выполнить проверку доступности с другими условиями в 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
}
Любой код, который использует API iOS 11 внутри блока if
или в some_condition
, все равно будет генерировать предупреждения о неохраняемой доступности, даже если гарантировано, что эти фрагменты кода могут быть достигнуты только тогда, когда на iOS 11 +.
Я мог бы превратить его в два вложенных if
s, но тогда код 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();
}
Может ли кто-нибудь придумать лучшее решение?