如何在 Swift 中消除警告?

Posted

技术标签:

【中文标题】如何在 Swift 中消除警告?【英文标题】:How to silence a warning in Swift? 【发布时间】:2015-07-21 13:27:54 【问题描述】:

我有一段代码会产生大量警告(不推荐使用的 API)

使用 clang* 我可以做到:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    ...
#pragma clang diagnostic pop

但这在 Swift 中不起作用。

如何在 Swift 中做到这一点?

注意:我不想在全局范围内禁用警告,甚至在文件范围内也不想禁用,而只是在我的源代码的特定部分禁用特定警告。

我确实想要条件编译(这是假定重复的建议答案)。 我只想在不使用新 API 的情况下消除警告。

【问题讨论】:

Swift alternative for #pragma clang diagnostic 的可能重复项 这不是重复的。另一个问题无法回答这个问题。 @ClausJørgensen 以何种方式无法回答这个问题?如链接问题的答案中所述,没有其他方法。只是条件编译或新的#available 宏,开发人员应该使用新方法并在新方法不可用时回退到旧方法。 @robertvojta 不,正如答案所做的那样,事实上,not 声明没有其他方法可以使警告静音。 这不是骗子。如果您因缺少初始化程序而收到警告怎么办? 【参考方案1】:

截至 2021 年,Xcode 13.0,共识是没有办法实现这一点。

如果 Apple 添加该功能,我将更新/编辑此答案。

把它放在你的 WWDC 2022 愿望清单中!

【讨论】:

该死的,这太糟糕了。它失控了sometimes。至少可以说很烦人。 我想一百万次否决这个答案,但它确实很好地回答了这个问题,所以 +1 :-) @Isuru 那时我会很恼火,只能重建整个事情。猜猜警告有效 Swift 不太可能获得类似的功能。目标是不创建不同的语言方言。相关讨论:twitter.com/jckarter/status/972894889221414912 太令人沮丧了!感谢您更新此答案。【参考方案2】:

在 Swift 中没有消除弃用警告的通用结构,但有一种解决方法可以在许多情况下应用

假设您在类 Foo 上有一个方法 getLatestImage(),它使用了已弃用的方法/类。

使用@available 就像 Daniel Thorpe 描述的那样来消除方法中内部的所有警告:

@available(ios, deprecated: 9.0)
func getLatestImage() -> UIImage? 
    ...

现在您想调用方法getLatestImage() 而不会收到弃用警告。您可以通过首先定义协议和扩展来实现:

private protocol GetLatestImage 
    func getLatestImage() -> UIImage?

extension Foo: GetLatestImage 

然后在没有弃用警告的情况下调用该方法。

如果fooFoo 的一个实例:

(foo as GetLatestImage).getLatestImage() // no deprecation warning

如果你想调用 Foo 的静态属性/函数:

(Foo.self as GetLatestImage.Type).someStaticProperty

结果是您的 Swift 代码使用了已弃用的 API,而没有任何弃用警告。

【讨论】:

太聪明了。有点邪恶? :) 但太好了。非常适合用例,例如在持续使用已弃用的 AddressBook 框架的某些方面时抑制警告,但有一个替代品实际上并没有提供所有必需的功能。谢谢。 如果可行,我会送你六包你最喜欢的饮料。先生,你有一个杰出的头脑,谢谢。 @John 感谢您的客气话!它确实有效,我不得不想出它,因为我们将警告视为代码库中的错误,并且有一个部分仍在使用已弃用的库。 @John 你给他寄了六包吗? :P 这太棒了。天才。谢谢。 你是个邪恶的天才。【参考方案3】:

实际上,您可以通过在封闭的逻辑结构(即函数/类型)中使用@available 来抑制这些警告。

例如,假设您有一些使用 AddressBook 框架的代码,但您是针对 iOS 9 构建的。

@available(iOS, deprecated: 9.0)
func addressBookStatus() -> ABAuthorizationStatus 
    return ABAddressBookGetAuthorizationStatus()

从 Xcode 7.0.1 开始,这将阻止显示内联警告。

【讨论】:

是的,但是当您调用 addressBookStatus()... 时,您会看到同样的警告,并标记为已弃用。 专业提示:如果您想在整个班级中保持沉默,只需将这只小狗猛击到您的班级声明上方(例如:class ViewController: UIViewController @Sirens 然后你每次调用这个类时都会看到这个警告☹️(至少在 Xcode 8 中) 是否有人通过此修复成功消除了 all 已弃用的警告?我能够将它们的数量减少到只有 一个,但我没有找到摆脱最后一个的方法。有什么建议吗? 那么如何使用它来消除警告“从'CGFloat.NativeType'(又名'Double')转换为不相关的类型'Float'总是失败”当我'我在做if CGFloat(0).native is Float … ?答:我不使用这个,因为你没有回答问题。【参考方案4】:

我遇到了类或结构之外的***函数的问题:

@available(*, deprecated)
func GetImage(url: URL) -> UIImage?  ... 

我与 Apple 的一位工程师交谈过,他们告诉我,您可以通过协议隐藏实现并将扩展标记为已弃用。让我们看看它是如何工作的:

    为要包装的函数创建一个具有相似签名的协议。 在扩展中的任何类或结构上使用该协议。 将扩展程序标记为已弃用。

扩展程序中的所有内容都不会显示任何弃用警告。

protocol ImageStoreProtocol 
    func imageFromURL(_ url: URL) -> UIImage?


class ImageStore 

@available(*, deprecated)
extension ImageStore: ImageStoreProtocol 
    func imageFromURL(_ url: URL) -> UIImage? 
        return GetImage(url: url) // Warning does't show up
    

【讨论】:

因为官方 Apple lifehack 的支持 :)【参考方案5】:

虽然目前无法在 Swift 中消除弃用警告,但从技术上讲,您可以通过编辑头文件来对特定符号执行此操作。

复制已弃用的符号名称 选择File > Open Quickly

粘贴符号并按Enter

确保在“快速打开”框中禁用了 Swift 图标

选择File > Show in Finder

如有必要,更改文件权限以允许编辑 编辑符号的弃用宏。请参阅周围的 API 以供参考。例如。替换:

__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_10, __IPHONE_3_0, __IPHONE_8_0)

__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)

现在有一个不那么令人分心的警告,您无能为力。

我知道,它很脏。但如果当前 SDK 中没有可用的替代 API,它应该是安全的。一旦新版本的 Xcode 出现,更改将被覆盖,您将再次看到警告。然后您可以测试新的 SDK 和操作系统,以确保已弃用的 API 仍然可用并且没有被替换。

如果您能提出任何缺点,请发表评论。

【讨论】:

支持机智,但它会在我的嘴里留下肮脏的味道:P

以上是关于如何在 Swift 中消除警告?的主要内容,如果未能解决你的问题,请参考以下文章

如何消除 GCC 中的外部库/第三方警告 [重复]

如何消除“前导和尾随约束……已经存在中心约束”警告

生成代码文档时如何消除意外缩进警告的原因?

Android - 如何消除这些 gradle/proguard 警告?

如何消除 TT 的“打印中的宽字符”警告?

如何消除 _logistic 回归上的 sklearn 警告