Swift替代#pragma clang诊断

Tom*_* C. 15 macros objective-c clang c-preprocessor swift

问题

我最近在这段代码中的第三方实用程序(WEPopover)中遇到警告:

_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;
Run Code Online (Sandbox Code Playgroud)

这产生了以下警告:

warning: 'contentSizeForViewInPopover' is deprecated: first deprecated in iOS 7.0 - Use UIViewController.preferredContentSize instead. [-Wdeprecated-declarations]
            _effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;
Run Code Online (Sandbox Code Playgroud)

Objective-C中的一个临时修复是使用pragma clang诊断来消除错误(我将让代码作者处理一个真正的修复).所以我修改了代码:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
            _effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;

#pragma clang diagnostic pop
Run Code Online (Sandbox Code Playgroud)

哪个工作得很好,但是这让我想一想,如果存在任何替代方案,在Swift编码时需要沉默类似的误报警告?

注意事项

我观察到这样一个事实:我可以在项目范围内停用此类警告(使用Xcode设置),但我想考虑如上所述的内联问题.我还考虑在我的Swift项目中将.define添加到.bridging-header.h文件中并以某种方式利用它; 但是我正在寻找一个针对这个问题的Swift特定解决方案.我确实知道pragma已不再可用,我搜索过SO并发现类似但不重复的问题.

更新的决议:Swift 2.0

提供的答案解决了我对内联警告的担忧.availability命令应该允许完全避免这样的问题,因为在编译时会警告一个问题.

Apple的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 
 }
Run Code Online (Sandbox Code Playgroud)

"

摘录自:Apple Inc."The Swift Programming Language(Swift 2 Prerelease)."iBooks.https://itun.es/us/k5SW7.l "

除非满足可用条件,否则甚至可以使用guard语句结合可用性来提前退出范围.

guard #available(iOS 8.0, OSX 10.10, *) else { return }
Run Code Online (Sandbox Code Playgroud)

摘录自:Apple Inc."将Swift与Cocoa和Objective-C一起使用(Swift 2 Prerelease)."iBooks.https://itun.es/us/utTW7.l

此外,我对处理宏的相关问题如下所述.请记住,Swift没有预处理器,这些工具看起来就像是要走的路.

" 简单的宏

在通常使用#define指令在C和Objective-C中定义基本常量的地方,在Swift中使用全局常量.例如,常量定义#define FADE_ANIMATION_DURATION 0.35可以在Swift中更好地表达,让FADE_ANIMATION_DURATION = 0.35.因为简单的类似常量的宏直接映射到Swift全局变量,所以编译器会自动导入在C和Objective-C源文件中定义的简单宏."

摘录自:Apple Inc."将Swift与Cocoa和Objective-C一起使用(Swift 2 Prerelease)."iBooks.https://itun.es/us/utTW7.l

" 复杂的宏

复杂的宏在C和Objective-C中使用,但在Swift中没有对应的.复杂的宏是不定义常量的宏,包括带括号的,类似函数的宏.您可以在C和Objective-C中使用复杂的宏来避免类型检查约束或避免重新输入大量的样板代码.但是,宏可能使调试和重构变得困难.在Swift中,您可以使用函数和泛型来实现相同的结果,而不会有任何妥协.因此,"C和Objective-C源文件中的复杂宏不能用于您的Swift代码."

摘录自:Apple Inc."将Swift与Cocoa和Objective-C一起使用(Swift 2 Prerelease)."iBooks.https://itun.es/us/utTW7.l

API的开发人员将能够使用以下方式标记Swift中函数的可用性:

available(iOS 8.0, OSX 10.10, *)
func useShinyNewFeature() {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

摘录自:Apple Inc."将Swift与Cocoa和Objective-C一起使用(Swift 2 Prerelease)."iBooks.https://itun.es/us/utTW7.l

将这些标记添加到为Swift重写的函数似乎是维护Frameworks向后兼容性的好方法.保护/可用组合将允许这些框架的用户根据需要调整逻辑.这让我放心地处理内联警告,API回退和宏.

Bla*_*man 2

截至 2.0 版本(在撰写本文时目前处于测试阶段),Swift 仍然不包含预处理器,并且看起来不会很快改变(如果有的话)。预处理器允许的有益功能以各种方式内置到语言本身中(我不会在这里介绍所有这些,请参阅文档)并且是编译时级别的功能。

我确实想提一下您可能正在寻找的两个功能(一个旧功能,一个新功能):

  1. 条件编译- 正如使用 Swift 与 Cocoa 和 Objective-C中所述,您可以实现条件编译语句,该语句允许您仅编译给定特定操作系统或处理器架构的代码。如果看起来像这样:

在此输入图像描述

  1. 检查 API 可用性- 正如Swift 编程语言中所述,您现在可以根据平台和操作系统版本检查 API 可用性。这将允许您利用较新的 API,同时允许您处理该功能在较旧(或不同)的平台或操作系统上不可用的情况。您可以使用它来替代替代实现或向用户提供解释。如果看起来像这样:

在此输入图像描述

这些工具(以及语言中内置的许多其他工具)应该允许开发人员替换 Objective-C 和 C 预处理器宏。就我个人而言,我认为它们是一个巨大的进步。