简体   繁体   English

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

[英]Xcode 8 / Swift 3: “Expression of type UIViewController? is unused” warning

I've got the following function which compiled cleanly previously but generates a warning with Xcode 8. 我有以下功能,以前干净地编译,但使用Xcode 8生成警告。

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

"Expression of type "UIViewController?" is unused". “表达式类型”UIViewController?“未使用”。

Why is it saying this and is there a way to remove it? 为什么要说这个,有没有办法删除它?

The code executes as expected. 代码按预期执行。

TL;DR TL; DR

popViewController(animated:) returns UIViewController? popViewController(animated:)返回UIViewController? , and the compiler is giving that warning since you aren't capturing the value. ,并且编译器正在发出警告,因为您没有捕获该值。 The solution is to assign it to an underscore: 解决方案是将其分配给下划线:

_ = navigationController?.popViewController(animated: true)

Swift 3 Change Swift 3改变

Before Swift 3, all methods had a "discardable result" by default. 在Swift 3之前,默认情况下所有方法都有“可丢弃的结果”。 No warning would occur when you did not capture what the method returned. 如果未捕获方法返回的内容,则不会发出警告。

In order to tell the compiler that the result should be captured, you had to add @warn_unused_result before the method declaration. 为了告诉编译器应该捕获结果,您必须在方法声明之前添加@warn_unused_result It would be used for methods that have a mutable form (ex. sort and sortInPlace ). 它将用于具有可变形式的方法(例如sortsortInPlace )。 You would add @warn_unused_result(mutable_variant="mutableMethodHere") to tell the compiler of it. 您可以添加@warn_unused_result(mutable_variant="mutableMethodHere")来告诉编译器。

However, with Swift 3, the behavior is flipped. 但是,使用Swift 3时,行为会被翻转。 All methods now warn that the return value is not captured. 现在所有方法都警告不会捕获返回值。 If you want to tell the compiler that the warning isn't necessary, you add @discardableResult before the method declaration. 如果要告诉编译器不需要警告,请在方法声明之前添加@discardableResult

If you don't want to use the return value, you have to explicitly tell the compiler by assigning it to an underscore: 如果您不想使用返回值,则必须通过将其分配给下划线来明确告诉编译器:

_ = someMethodThatReturnsSomething()

Motivation for adding this to Swift 3: 将此添加到Swift 3的动机:

  • Prevention of possible bugs (ex. using sort thinking it modifies the collection) 防止可能的错误(例如使用sort思维它修改集合)
  • Explicit intent of not capturing or needing to capture the result for other collaborators 不捕获或需要捕获其他协作者的结果的明确意图

The UIKit API appears to be behind on this, not adding @discardableResult for the perfectly normal (if not more common) use of popViewController(animated:) without capturing the return value. UIKit API似乎落后于此,没有为完全正常(如果不是更常见)使用popViewController(animated:)添加@discardableResult而不捕获返回值。

Read More 阅读更多

When life gives you lemons, make an extension: 当生活给你柠檬时,做一个扩展:

import UIKit

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

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

Note that adding something like @discardableResult func pop(animated: Bool) -> UIViewController? 注意添加类似@discardableResult func pop(animated: Bool) -> UIViewController? will result in the same warning you are trying to avoid. 将导致您试图避免的相同警告。

With the extension you can now write: 通过扩展,您现在可以编写:

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

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

Edit: Added popToRoot too. 编辑:也添加了popToRoot。

In Swift 3, ignoring the return value of a function that has a declared return value results in a warning. 在Swift 3中,忽略具有声明的返回值的函数的返回值会导致警告。

One way to opt out of this is to mark the function with the @discardableResult attribute. 选择退出此方法的一种方法是使用@discardableResult属性标记该函数。 Since you don't have control over this function, that won't work. 由于您无法控制此功能,因此无法使用。

The other method to get rid of the warning is to assign the value to _ . 摆脱警告的另一种方法是将值赋给_ This tells the compiler you know the method returns a value but you don't want to retain it in memory. 这告诉编译器您知道该方法返回一个值,但您不希望将其保留在内存中。

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

截图1

Although it work correctly if kept as it is but the number of warning increases. 虽然work correctly if kept as it isnumber of warning increases.number of warning increases.

The solution is to simply replace it with underscore ( _ ) though it seems to be ugly. 解决方案是简单地replace it with underscore ( _ )虽然它看起来很难看。

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

截图2

Use discardableResult in this condition. 在这种情况下使用discardableResult

According to < Swift Programming Language > , chapter Language Reference - Attributes. 根据<Swift Programming Language>,语言参考 - 属性一章。

discardableResult discardableResult

Apply this attribute to a function or method declaration to suppress the compiler warning when the function or method that returns a value is called without using its result. 将此属性应用于函数或方法声明,以在调用返回值的函数或方法而不使用其结果时抑制编译器警告。

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

There is also a demo in < Swift Programming Language > , chapter Language Guide - Methods. 还有<Swift Programming Language>中的演示,语言指南 - 方法一章。

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

Because it's not necessarily a mistake for code that calls the advance(to:) method to ignore the return value, this function is marked with the @discardableResult attribute. 因为调用advance(to :)方法忽略返回值的代码不一定是错误,所以此函数标有@discardableResult属性。 For more information about this attribute, see Attributes. 有关此属性的更多信息,请参阅属性。

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

If you want to go the road of extensions like CodeReaper's answer you should use @descardableResult . 如果你想像CodeReaper的答案那样走上扩展之路,你应该使用@descardableResult This keeps all the possibilities, but silences the warning. 这保留了所有可能性,但使警告静音。

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)
    }
}

Another way is you can unwrapped the self.navigationController? 另一种方法是你可以解开self.navigationController? value and call the popViewController function. value并调用popViewController函数。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM