问题
最近我在一个第三方工具(WEPopover)的这段代码中遇到了一个警告:
_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;
这会产生以下警告:
warning: 'contentSizeForViewInPopover' is deprecated: first deprecated in iOS 7.0 - Use UIViewController.preferredContentSize instead. [-Wdeprecated-declarations]
_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;
在Objective-C中,解决这个问题的一种临时方法是使用pragma clang diagnostic来消除错误(我会让代码作者处理真正的修复)。因此,我将代码修改如下:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;
#pragma clang diagnostic pop
问题
这段代码可以正常工作,但这让我考虑如果在编写Swift时需要消除类似的误报警告,是否存在任何替代方案?
考虑因素
我已经观察到,我可以在整个项目中停用此类警告(使用Xcode设置),但我想考虑上述内联问题。我还考虑在我的Swift项目中的.bridging-header.h文件中添加#define,并以某种方式利用它; 但是,我正在寻找解决此问题的特定于Swift的解决方案。我确实了解pragma不再可用,并且我已经搜索了SO并找到了类似但不重复的问题。
更新的解决方案:Swift 2.0
提供的答案处理了我对内联警告的担忧。可用性命令应该允许完全避免此类问题,因为在编译时会发出警告。
苹果的Swift书明确说明:
“您在if或guard语句中使用可用性条件来有条件地执行一块代码,具体取决于您要使用的API在运行时是否可用。编译器在验证该“代码块中的API是否可用时使用可用性条件中的信息。
if #available(iOS 9, OSX 10.10, *) {
// Use iOS 9 APIs on iOS, and use OS X v10.10 APIs on OS X
} else {
// Fall back to earlier iOS and OS X APIs
}
”
有人甚至可以使用guard语句和可用性结合,除非满足可用条件,否则提前退出范围。
guard #available(iOS 8.0, OSX 10.10, *) else { return }
此外,我对处理宏的相关问题进行了如下说明。请记住,Swift没有预处理器,这些工具似乎是可行的选择。
“简单宏”
在C和Objective-C中,您通常使用#define指令来定义原始常量,而在Swift中,则使用全局常量。例如,常量定义#define FADE_ANIMATION_DURATION 0.35可以用let FADE_ANIMATION_DURATION = 0.35更好地表达出来。因为类似常量的简单宏直接映射到Swift全局变量,编译器自动导入在C和Objective-C源文件中定义的简单宏。
“复杂宏”
复杂宏在C和Objective-C中使用,但在Swift中没有对应物。复杂宏是不定义常量的宏,包括带括号的函数样式宏。您在C和Objective-C中使用复杂宏以避免类型检查约束或避免重新输入大量样板代码。然而,宏可能会使调试和重构困难。在Swift中,您可以使用函数和泛型来实现相同的结果,而不需要进行任何妥协。因此,“在C和Objective-C源文件中的复杂宏不可用于Swift代码。”
摘自:Apple Inc. “使用Swift与Cocoa和Objective-C(Swift 2预发布版)。”iBooks. https://itun.es/us/utTW7.l API的开发者可以使用以下方式标记Swift中函数的可用性:
available(iOS 8.0, OSX 10.10, *)
func useShinyNewFeature() {
// ...
}
摘自:苹果公司。“使用Swift与Cocoa和Objective-C(Swift 2预发布版)。”iBooks. https://itun.es/us/utTW7.l
为Swift重写的函数添加这些标记似乎是保持框架向后兼容性的好方法。guard / available组合将允许那些框架的用户根据需要调整逻辑。这让我放心处理内联警告,API回退和宏等问题。