Swift替代#pragma clang诊断

时间:2015-02-06 01:49:50

标签: objective-c swift macros clang c-preprocessor

问题

我最近在这段代码中的第三方实用程序(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诊断来消除错误(我会让代码作者处理一个真正的修复)。所以我修改了代码:

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

#pragma clang diagnostic pop

问题

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

考虑

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

更新后的解决方案:Swift 2.0

提供的答案解决了我对内联警告的担忧。可用性命令应该允许完全避免这样的问题,因为会在编译时发出警告。

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 
 }

摘录自: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 }

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

此外,我对处理宏的相关问题如下所述。请记住,Swift没有预处理器这些工具似乎是要走的路。

  

简单宏

     

您通常使用#define指令的地方   在C和Objective-C中定义一个原始常量,在Swift中你使用一个   全局常数而不是。例如,常量定义#define   使用let可以在Swift中更好地表达FADE_ANIMATION_DURATION 0.35   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但没有对应的   在斯威夫特。复杂的宏是不定义常量的宏,   包括带括号的函数式宏。您使用复杂的宏   在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() {
    // ...
}

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

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

1 个答案:

答案 0 :(得分:2)

从版本2.0开始(目前处于测试阶段),Swift仍然不包含预处理器,并且不会很快发生变化(如果有的话)。预处理器允许的有益能力以各种方式构建在语言本身中(我不会在这里覆盖所有这些,请参阅文档)并且是编译时级别的功能。

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

  1. 条件编译 - 如Using Swift with Cocoa and Objective-C所述,您可以实现条件编译语句,只允许您在给定某些操作系统或处理器体系结构的情况下编译代码。如果看起来像这样:
  2. enter image description here

    1. 检查API可用性 - 如The Swift Programming Language所述,您现在可以根据平台和操作系统版本检查API可用性。这将允许您利用较新的API,同时允许您在较旧(或不同)平台或操作系统上无法使用该功能时进行处理。您可以在备用实现中使用它来进行子操作或向用户提供解释。如果看起来像这样:
    2. enter image description here

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