Reputation: 37581
I've got the following function which compiled cleanly previously but generates a warning with Xcode 8.
func exitViewController()
{
navigationController?.popViewController(animated: true)
}
"Expression of type "UIViewController?" is unused".
Why is it saying this and is there a way to remove it?
The code executes as expected.
Upvotes: 236
Views: 52196
Reputation: 954
Another way is you can unwrap the self.navigationController?
value and call the popViewController
function.
if let navigationController = navigationController {
navigationController.popViewController(animated: true)
}
Upvotes: -1
Reputation: 2699
Use discardableResult in this condition.
According to < Swift Programming Language > , chapter Language Reference - Attributes.
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.
@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.
Upvotes: 3
Reputation: 3687
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.
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)
}
}
Upvotes: 0
Reputation: 36447
Although it work correctly if kept as it is
but the number of warning increases.
The solution is to simply replace it with underscore ( _ )
though it seems to be ugly.
Eg. _ = navigationController?.popViewController(animated: true)
Upvotes: 5
Reputation: 6145
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?
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.
Upvotes: 38
Reputation: 9391
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:
_ = navigationController?.popViewController(animated: true)
Before Swift 3, all methods had a "discardable result" by default. 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. 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.
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.
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:
sort
thinking it modifies the collection)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.
Upvotes: 505
Reputation: 8092
In Swift 3, ignoring the return value of a function that has a declared return value results in a warning.
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.
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)
Upvotes: 24