本文介绍了Objective-C @available可以在更多条件下保持AND的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 Objective-C有 @available 表达式,允许您将代码块保护到至少某个操作系统版本,以便在使用API​​时不会发出无人看守的可用性警告仅适用于该操作系统版本。Objective-C has an @available expression in XCode 9+ / LLVM 5+ that allows you to guard a block of code to at least a certain OS version so that it won't emit unguarded availability warnings if you use APIs that are only available on that OS version.问题在于这种可用性保护只有在它是如果。如果您在任何其他情况下使用它,您会收到警告:The problem is that this availability guarding is that it only works if it's the sole expression in the condition of an if. If you use it in any other context, you get a warning:@available does not guard availability here; use if (@available) instead例如,如果你尝试AND它就不起作用中的其他条件的可用性检查,如果:So for example, it doesn't work if you try to AND the availability check with other conditions in the 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}任何使用iOS 11内部API的代码code>如果阻止或在 some_condition 仍然会产生无人看守的可用性警告,即使保证这些代码片段只能是在iOS 11 +上达到。Any code that uses iOS 11 APIs inside the if block or in some_condition still will generate unguarded availability warnings, even though it is guaranteed that those pieces of code can only be reached when on iOS 11+.我可以把它变成两个嵌套的如果 s,但接着是 else 代码必须重复,这很糟糕(特别是如果有很多代码):I could turn it into two nested ifs, but then the else code would have to be duplicated, which is bad (especially if it's lots of code):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 ,这使代码流难以遵循:I can avoid duplication by refactoring the else block code into an anonymous function, but that requires defining the else block before the if, which makes the code flow hard to follow: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();}有人能想出更好的解决方案吗?Can anyone come up with a better solution?推荐答案 #define SUPPRESS_AVAILABILITY_BEGIN \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wunsupported-availability-guard\"")\ _Pragma("clang diagnostic ignored \"-Wunguarded-availability-new\"")#define SUPPRESS_AVAILABILITY_END \ _Pragma("clang diagnostic pop")#define AVAILABLE_GUARD(platform, os, future, conditions, codeIfAvailable, codeIfUnavailable) \ SUPPRESS_AVAILABILITY_BEGIN \ if (__builtin_available(platform os, future) && conditions) {\ SUPPRESS_AVAILABILITY_END \ if (@available(platform os, future)) { \ codeIfAvailable \ } \ } \ else { \ SUPPRESS_AVAILABILITY_END \ codeIfUnavailable \ }用法:AVAILABLE_GUARD(iOS, 11.0, *, true, { printf("IS AVAILABLE");},{ printf("NOT AVAILABLE");});它的工作原理是使用@available作为具有附加可选条件的条件。由于你失去了守卫的能力,我压制了无人防守的警告,但我还在那里添加了一个额外的守卫以保护其余的代码..这使得它基本上没有任何损失.. It works by using @available as a condition with additional optional conditions. Since you lose the ability to "guard", I suppressed the unguarded warnings but I also added an extra guard there to guard the rest of the code.. This makes it so you essentially lost nothing..你得到了警卫,你得到了警告,你得到了额外的条件.. You get the guarding, you get the warnings gone and you get the extra conditions.. 这篇关于Objective-C @available可以在更多条件下保持AND的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-28 19:30