Swift替代#pragma clang诊断 [英] Swift alternative for #pragma clang diagnostic

查看:959
本文介绍了Swift替代#pragma clang诊断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题



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

  _effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover; 

这会产生以下警告:

 警告:'contentSizeForViewInPopover'已弃用:首先在iOS 7.0中弃用 - 改用UIViewController.preferredContentSize。 [-Wdeprecated-declarations] 
_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;

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

  #pragma clang诊断推送
#pragma clang diagnostic ignored-Wdeprecated-声明
_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;

#pragma clang诊断pop

问题



这只是很好,但是这让我考虑如果有什么替代存在的地方,在Swift中编码时需要沉默类似的假阳性警告?



注意事项



我观察到我可以停用此类警告项目(使用Xcode设置),但我想考虑内联问题,如上所述。我也考虑在我的Swift项目中添加一个#define到.bridging-header.h文件中,并以某种方式使用它。然而我正在寻找一个Swift的具体解决方案这个问题。



更新版本:Swift 2.0 / p>

提供的答案处理我对内联警告的关注。可用性命令应该允许完全避免这样的问题,因为在编译时会警告一个问题。



Apple的Swift书最后声明:


在if或guard语句中使用可用性条件来
有条件地执行一个代码块,这取决于您要使用的API
在运行时可用。编译器使用可用性条件下的
信息,当它验证该代码块中的
API可用时。




  if #available(iOS 9,OSX 10.10,*){
//在iOS上使用iOS 9 API,并在操作系统上使用OS X v10.10 API X
} else {
//回到早期的iOS和OS X API
}



摘录自Apple Inc.Swift编程语言(Swift 2 Prerelease)iBooks。 ,您现在可以根据平台和操作系统版本检查API可用性。这将允许您利用较新的API,同时允许您处理何时该功能在较旧(或不同)平台或操作系统上不可用。您可以在备用实施中使用此子选项或向用户提供说明。如果看起来像这样:



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


Problem

I recently encountered a warning in a third party utility (WEPopover) in this piece of code:

_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;

This was generating the following warning:

warning: 'contentSizeForViewInPopover' is deprecated: first deprecated in iOS 7.0 - Use UIViewController.preferredContentSize instead. [-Wdeprecated-declarations]
            _effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;

One temporary fix for this in Objective-C is to use pragma clang diagnostic to silence the error (I'll let the code author deal with a true fix). So I revised the code like so:

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

#pragma clang diagnostic pop

Question

Which works just fine but this led me to consider what if any alternative exists where one would need to silence a similar false positive warning when coding in Swift?

Considerations

I have observed the fact that I can deactivate such warnings project wide (using Xcode settings) but I want to consider the inline problem as noted above. I've also considered adding a #define into a .bridging-header.h file within my Swift project and somehow making use of that; however I am looking for a Swift specific solution to this problem. I do understand that pragma is no longer available and I have searched SO and found similar but not duplicate questions.

UPDATED RESOLUTION: Swift 2.0

The answer provided handles my concern about inline warnings. The availability command should allow such problems to be avoided altogether because one would be warned at compile time.

Apple's Swift book definitively states:

"You use an availability condition in an if or guard statement to conditionally execute a block of code, depending on whether the APIs you want to use are available at run time. The compiler uses the information from the availability condition when it verifies that the APIs in that "block of code are available.

 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 
 }

"

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

One could even use the guard statement combined with availability to exit the scope early unless the available conditions are satisfied.

guard #available(iOS 8.0, OSX 10.10, *) else { return }

Excerpt From: Apple Inc. "Using Swift with Cocoa and Objective-C (Swift 2 Prerelease)." iBooks. https://itun.es/us/utTW7.l

Furthermore, my related concerns on handling macros are addressed as noted below. Keeping in mind that Swift has no preprocessor these tools seem like the way to go.

"Simple Macros

Where you typically used the #define directive to define a primitive constant in C and Objective-C, in Swift you use a global constant instead. For example, the constant definition #define FADE_ANIMATION_DURATION 0.35 can be better expressed in Swift with let FADE_ANIMATION_DURATION = 0.35. Because simple constant-like macros map directly to Swift global variables, the compiler automatically imports simple macros defined in C and Objective-C source files."

Excerpt From: Apple Inc. "Using Swift with Cocoa and Objective-C (Swift 2 Prerelease)." iBooks. https://itun.es/us/utTW7.l

"Complex Macros

Complex macros are used in C and Objective-C but have no counterpart in Swift. Complex macros are macros that do not define constants, including parenthesized, function-like macros. You use complex macros in C and Objective-C to avoid type-checking constraints or to avoid retyping large amounts of boilerplate code. However, macros can make debugging and refactoring difficult. In Swift, you can use functions and generics to achieve the same results without any compromises. Therefore, the "complex macros that are in C and Objective-C source files are not made available to your Swift code."

Excerpt From: Apple Inc. "Using Swift with Cocoa and Objective-C (Swift 2 Prerelease)." iBooks. https://itun.es/us/utTW7.l

The developer of the API will be able to mark the availability of functions in Swift using:

available(iOS 8.0, OSX 10.10, *)
func useShinyNewFeature() {
    // ...
}

Excerpt From: Apple Inc. "Using Swift with Cocoa and Objective-C (Swift 2 Prerelease)." iBooks. https://itun.es/us/utTW7.l

Adding these markers to functions rewritten for Swift seems like a good way to maintain backward compatibility for Frameworks. The guard/available combination will allow users of those frameworks to adjust logic as necessary. Which sets my mind at ease about handling both in-line warnings, API fallback, and macros in general.

解决方案

As of version 2.0 (currently in beta as of this writing), Swift still does not include a preprocessor and that doesn't look to change anytime soon (if ever). The beneficial abilities that preprocessors allow are built into the language itself in various ways (I won't cover all of them here, see the docs) and are compile-time level features.

There are two features I do want to mention (one old, one new) that may be what you're looking for:

  1. Conditional Compilation - As covered in Using Swift with Cocoa and Objective-C, you can implement conditional compilation statements that allow you to only compile code given certain operating systems or processor architectures. If looks something like this:

  1. Checking for API Availability - As covered in The Swift Programming Language, you can now check for API availability based on platform and OS version. This will allow you to take advantage of newer API's while allowing you to handle when that feature isn't available on an older (or different) platform or OS. You could use this to sub in an alternate implementation or present an explanation to the user. If looks something like this:

These tools (along with many others built into the language) should allow a developer to replace the Objective-C and C preprocessor macros. Personally, I think they are a huge improvement.

这篇关于Swift替代#pragma clang诊断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆