我得到了下面的函数,之前编译干净,但用Xcode 8生成了一个警告。

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

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

它为什么这么说,有办法去掉它吗?

代码按预期执行。


当前回答

另一种方法是展开self。navigationcontroller ?值并调用popViewController函数。

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

其他回答

在这种情况下使用discardableResult。

参考《Swift Programming Language >》,章节语言参考-属性。

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

在< Swift Programming Language >,章节语言指南-方法中也有一个演示。

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

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

博士TL;

popViewController(animated:)返回UIViewController?,编译器会给出警告,因为你没有捕获值。解决方案是将其赋值为一个下划线:

_ = navigationController?.popViewController(animated: true)

快速变化

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

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

然而,在Swift 3中,这种行为发生了反转。现在所有方法都警告未捕获返回值。如果你想告诉编译器这个警告是不必要的,你可以在方法声明之前添加@discardableResult。

如果你不想使用返回值,你必须通过将它赋值给一个下划线显式地告诉编译器:

_ = someMethodThatReturnsSomething()

加入Swift 3的动机:

防止可能的错误(例如,使用sort认为它修改了集合) 不捕获或需要为其他合作者捕获结果的明确意图

UIKit API似乎在这方面落后了,没有为popViewController(animated:)的正常使用添加@discardableResult而不捕获返回值。

阅读更多

SE-0047快速进化提案 接受修订后的提案

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

选择不这样做的一种方法是使用@discardableResult属性标记函数。因为你不能控制这个函数,所以这行不通。

消除警告的另一种方法是将值赋值为_。这告诉编译器你知道这个方法返回一个值,但是你不想把它保留在内存中。

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

另一种方法是展开self。navigationcontroller ?值并调用popViewController函数。

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

如果你想要像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)
    }
}