XCode 9+ / LLVM 5+中的Objective-C具有@available
表达式,允许您保护一段代码至少到某个OS版本,以便如果您使用仅在该OS版本上可用的API,则不会发出未受保护的可用性警告。
问题是这种可用性保护仅在if
条件中是唯一的表达式时才有效。如果在任何其他上下文中使用它,将会收到警告:
@available does not guard availability here; use if (@available) instead
例如,如果您尝试将可用性检查与if
中的其他条件进行AND运算,则无法正常工作:
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
}
即使可以保证这些代码只能在 iOS 11+ 上运行,但是任何使用 iOS 11 APIs 的代码仍将在 if
块或 some_condition
中生成未经保护的可用性警告。
我可以把它变成两个嵌套的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
块代码重构为匿名函数,我可以避免重复,但这需要在if
之前定义else
块,这会使代码流程难以理解:
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();
}
有人能提出更好的解决方案吗?
if (@available...)
的else
块中,难道你也不需要针对some_condition
进行测试吗? - Nicolas Miari[self elseMethod];
替换elseBlock()
即可。 - RobP