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

时间:2016-06-15 18:24:58

标签: ios swift

我有以下功能,以前干净利落地编译但是使用Xcode 8生成警告。

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

"类型" UIViewController的表达式?"未被使用"。

为什么要这样说,有没有办法将其删除?

代码按预期执行。

7 个答案:

答案 0 :(得分:494)

TL; DR

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

_ = navigationController?.popViewController(animated: true)

Swift 3 Change

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

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

但是,使用Swift 3时,行为会被翻转。现在所有方法都警告不会捕获返回值。如果您想告诉编译器警告不是必需的,可以在方法声明之前添加@discardableResult

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

_ = someMethodThatReturnsSomething()

将此添加到Swift 3的动机:

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

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

了解更多

答案 1 :(得分:38)

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

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。

答案 2 :(得分:24)

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

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

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

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

答案 3 :(得分:5)

Screenshot 1

虽然work correctly if kept as it is但是number of warning increases.

解决方案只是replace it with underscore ( _ ),虽然看起来很难看。

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

Screenshot 2

答案 4 :(得分:1)

在这种情况下使用 discardableResult

根据< Swift编程语言> ,章节语言参考 - 属性。

  

discardableResult

     

将此属性应用于函数或方法声明,以便在不使用其结果的情况下调用返回值的函数或方法时禁止编译器警告。

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Attributes.html#//apple_ref/doc/uid/TP40014097-CH35-ID347

还有一个演示版< Swift编程语言> ,语言指南 - 方法一章。

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

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

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html#//apple_ref/doc/uid/TP40014097-CH15-ID234

答案 5 :(得分:0)

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

答案 6 :(得分:-1)

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

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