ios Xcode 8 / Swift 3:“UIViewController 类型的表达式?未使用”警告
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37843049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Xcode 8 / Swift 3: "Expression of type UIViewController? is unused" warning
提问by Gruntcakes
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.
代码按预期执行。
回答by tktsubota
TL;DR
TL; 博士
popViewController(animated:)
returns UIViewController?
, and the compiler is giving that warning since you aren't capturing the value. The solution is to assign it to an underscore:
popViewController(animated:)
return UIViewController?
,并且编译器会发出该警告,因为您没有捕获该值。解决方案是将其分配给下划线:
_ = navigationController?.popViewController(animated: true)
Swift 3 Change
斯威夫特 3 变化
Before Swift 3, all methods had a "discardable result" by default. No warning would occur when you did not capture what the method returned.
在 Swift 3 之前,所有方法默认都有一个“可丢弃的结果”。当您没有捕获方法返回的内容时,不会出现警告。
In order to tell the compiler that the result should be captured, you had to add @warn_unused_result
before the method declaration. It would be used for methods that have a mutable form (ex. sort
and sortInPlace
). You would add @warn_unused_result(mutable_variant="mutableMethodHere")
to tell the compiler of it.
为了告诉编译器应该捕获结果,您必须@warn_unused_result
在方法声明之前添加。它将用于具有可变形式(例如sort
和sortInPlace
)的方法。你会添加@warn_unused_result(mutable_variant="mutableMethodHere")
告诉编译器它。
However, with Swift 3, the behavior is flipped. 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.
但是,在 Swift 3 中,行为发生了翻转。现在,所有方法都会警告未捕获返回值。如果您想告诉编译器不需要警告,请@discardableResult
在方法声明之前添加。
If you don't want to use the return value, you have to explicitlytell 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) - Explicit intent of not capturing or needing to capture the result for other collaborators
- 预防可能的错误(例如,
sort
认为它会修改集合) - 不捕获或需要为其他协作者捕获结果的明确意图
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 似乎落后于此,没有添加@discardableResult
完全正常(如果不是更常见)使用popViewController(animated:)
而不捕获返回值。
Read More
阅读更多
回答by CodeReaper
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)
}
}
Notethat adding something like @discardableResult func pop(animated: Bool) -> UIViewController?
will result in the same warning you are trying to avoid.
请注意,添加类似的内容@discardableResult func pop(animated: Bool) -> UIViewController?
将导致您试图避免的相同警告。
With the extension you can now write:
使用扩展,您现在可以编写:
func exitViewController()
{
navigationController?.pop(animated: true)
}
func popToTheRootOfNav() {
navigationController?.popToRoot(animated: true)
}
Edit: Added popToRoot too.
编辑:也添加了 popToRoot。
回答by Matthew Seaman
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. Since you don't have control over this function, that won't work.
选择退出的一种方法是用@discardableResult
属性标记函数。由于您无法控制此功能,因此无法使用。
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)
回答by Jayprakash Dubey
Although it work correctly if kept as it is
but the number of warning increases.
虽然它work correctly if kept as it is
但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)
回答by black_pearl
Use discardableResultin this condition.
在这种情况下使用discardableResult。
According to < Swift Programming Language > , chapter Language Reference - Attributes.
根据 <Swift Programming Language> ,章节语言参考 - 属性。
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.
可丢弃的结果
将此属性应用于函数或方法声明以在调用返回值的函数或方法而不使用其结果时抑制编译器警告。
There is also a demo in < Swift Programming Language > , chapter Language Guide - Methods.
在 <Swift Programming Language> 中还有一个 demo,章节 Language Guide - Methods。
@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. For more information about this attribute, see Attributes.
因为调用 Advance(to:) 方法忽略返回值的代码不一定是错误的,所以这个函数用@discardableResult 属性标记。有关此属性的更多信息,请参阅属性。
回答by Casper Zandbergen
If you want to go the road of extensions like CodeReaper's answer you should use @descardableResult
. This keeps all the possibilities, but silences the warning.
如果你想走像 CodeReaper's answer 这样的扩展之路,你应该使用@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)
}
}
回答by muazhud
Another way is you can unwrapped the self.navigationController?
value and call the popViewController
function.
另一种方法是您可以解开该self.navigationController?
值并调用该popViewController
函数。
if let navigationController = navigationController {
navigationController.popViewController(animated: true)
}