ChatGPT解决这个技术问题 Extra ChatGPT

Xcode 8 / Swift 3:“UIViewController 类型的表达式?未使用”警告

我有以下函数,它以前编译得很干净,但会用 Xcode 8 生成警告。

func exitViewController()
{
    navigationController?.popViewController(animated: true)
}

“未使用“UIViewController?”类型的表达式”。

为什么会这样说,有没有办法删除它?

代码按预期执行。


t
tktsubota

TL;博士

popViewController(animated:) 返回 UIViewController?,编译器发出警告,因为您没有捕获该值。解决方案是将其分配给下划线:

_ = navigationController?.popViewController(animated: true)

斯威夫特 3 改变

在 Swift 3 之前,所有方法默认都有一个“可丢弃的结果”。当您没有捕获方法返回的内容时,不会出现警告。

为了告诉编译器应该捕获结果,您必须在方法声明之前添加 @warn_unused_result。它将用于具有可变形式的方法(例如 sortsortInPlace)。您将添加 @warn_unused_result(mutable_variant="mutableMethodHere") 来告诉编译器它。

然而,在 Swift 3 中,行为发生了翻转。现在,所有方法都警告未捕获返回值。如果您想告诉编译器不需要警告,请在方法声明之前添加 @discardableResult

如果您不想使用返回值,则必须通过将其分配给下划线来明确告诉编译器:

_ = someMethodThatReturnsSomething()

将其添加到 Swift 3 的动机:

预防可能的错误(例如,使用排序认为它会修改集合)

不捕获或需要为其他协作者捕获结果的明确意图

UIKit API 似乎落后于此,没有添加 @discardableResult 以完全正常(如果不是更常见)使用 popViewController(animated:) 而不捕获返回值。

阅读更多

SE-0047 快速进化提案

已接受的带有修订的提案


这(在我看来)绝对是 Swift 2 的后退一步,尤其是当有这样的方法时,即使它们确实返回一个值,也有完全有效的用例,你只是不使用它。
1. 您不需要 let:您可以只分配给 _ 而无需在其前面加上 letvar
@rickster 不知道这会增加答案。
2.@NicolasMiari File a bug。对于确实返回值但预计可能会忽略返回值的函数,有一个注释 (@discardableResult)。 UIKit 只是没有将该注释应用到他们的 API。
这是可怕的语法。他们为什么要这样做?呸。
S
StuartM

当生活给你柠檬时,做一个延伸:

import UIKit

extension UINavigationController {
    func pop(animated: Bool) {
        _ = self.popViewController(animated: animated)
    }

    func popToRoot(animated: Bool) {
        _ = self.popToRootViewController(animated: animated)
    }
}

注意,添加类似 @discardableResult func pop(animated: Bool) -> UIViewController? 的内容将导致您试图避免的相同警告。

使用扩展,您现在可以编写:

func exitViewController()
{
    navigationController?.pop(animated: true)
}

func popToTheRootOfNav() {
    navigationController?.popToRoot(animated: true)
}

编辑:也添加了 popToRoot。


这应该是公认的解决方案,因为它是对肯定会在 Xcode 更新中修复的内容的最干净的修复。
M
Matthew Seaman

在 Swift 3 中,忽略具有声明返回值的函数的返回值会导致警告。

选择退出的一种方法是使用 @discardableResult 属性标记函数。由于您无法控制此功能,因此它不起作用。

消除警告的另一种方法是将值分配给 _。这告诉编译器您知道该方法返回一个值,但您不想将其保留在内存中。

let _ = navigationController?.popViewController(animated: true)

我想我们必须坚持使用丑陋的 _,直到 Apple 用这个新属性更新 UIKit。
不幸的是 @discardableResult 不起作用(至少它仍然在 8b4 中发出嘶哑的声音)。弗里德里希席勒喜欢烂苹果。可能是口味问题:-(
J
Jayprakash Dubey

https://i.stack.imgur.com/FYFrs.png

虽然它 work correctly if kept as it isnumber of warning increases.

解决方案是简单地 replace it with underscore ( _ ) 虽然它看起来很丑陋。

Eg.  _ = navigationController?.popViewController(animated: true)

https://i.stack.imgur.com/l2yF1.png


b
b m gevariya

在这种情况下使用discardableResult。

根据< Swift Programming Language > , chapter Language Reference - Attributes

discardableResult 将此属性应用于函数或方法声明,以在调用返回值的函数或方法而不使用其结果时抑制编译器警告。

< Swift Programming Language >, chapter Language Guide - Methods 中还有一个演示。

@discardableResult
mutating func advance(to level: Int) -> Bool {
    ...
    return true
}

因为调用advance(to:)方法忽略返回值的代码不一定是错误,所以这个函数用@discardableResult属性标记。有关此属性的详细信息,请参阅属性。


C
Casper Zandbergen

如果您想走类似 CodeReaper 的答案的扩展之路,您应该使用 @descardableResult。这保留了所有可能性,但使警告静音。

import UIKit

extension UINavigationController {
    @discardableResult func pop(animated: Bool) -> UIViewController? {
        return self.popViewController(animated: animated)
    }

    @discardableResult func popToRoot(animated: Bool) -> [UIViewController]? {
        return self.popToRootViewController(animated: animated)
    }
}

b
b m gevariya

另一种方法是您可以解开 self.navigationController? 值并调用 popViewController 函数。

if let navigationController = navigationController {
    navigationController.popViewController(animated: true)
}

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅