【发布时间】:2018-04-08 11:41:18
【问题描述】:
Objective-C 在 XCode 9+ / LLVM 5+ 中有一个 @available expression,它允许您将代码块保护到至少某个操作系统版本,这样如果您使用的 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
}
任何在 if 块或 some_condition 中使用 iOS 11 API 的代码仍会生成无人看管的可用性警告,即使保证只有在 iOS 11+ 上才能访问这些代码。
我可以把它变成两个嵌套的ifs,但是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进行测试也 ...? -
@NicolasMiari:不
-
我认为您最后一个解决方案的变体是最好的,使用方法而不是块,以便方法定义可以在所有这些条件代码之后。只需将
elseBlock()替换为[self elseMethod];
标签: ios objective-c xcode9 availability