Xcode 8 / Swift 3: «Выражение типа UIViewController? не используется »предупреждение

219

У меня есть следующая функция, которая скомпилирована ранее, но генерирует предупреждение с Xcode 8.

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

"Выражение типа" UIViewController? "не используется".

Почему он говорит это и есть способ его удалить?

Код выполняется, как ожидалось.

Теги:

6 ответов

481
Лучший ответ

TL; DR

popViewController(animated:) возвращает UIViewController?, и компилятор дает это предупреждение, так как вы не фиксируете значение. Решение состоит в том, чтобы назначить его символу подчеркивания:

_ = navigationController?.popViewController(animated: true)

Swift 3 Изменить

Перед тем, как Swift 3, по умолчанию все методы имели "отбрасываемый результат". Предупреждение не будет происходить, когда вы не поймете, что возвратил метод.

Чтобы сообщить компилятору, что результат должен быть захвачен, вам нужно было добавить @warn_unused_result перед объявлением метода. Он будет использоваться для методов, имеющих изменяемую форму (например, sort и sortInPlace). Вы должны добавить @warn_unused_result(mutable_variant="mutableMethodHere"), чтобы сообщить об этом компилятору.

Однако, с Swift 3, поведение перевернуто. Все методы теперь предупреждают, что возвращаемое значение не будет записано. Если вы хотите сообщить компилятору, что предупреждение не требуется, вы добавляете @discardableResult перед объявлением метода.

Если вы не хотите использовать возвращаемое значение, вам нужно явно указать компилятору, присвоив его знаку подчеркивания:

_ = someMethodThatReturnsSomething()

Мотивация для добавления этого в Swift 3:

  • Предотвращение возможных ошибок (например, с помощью sort, считающих, что он изменяет коллекцию)
  • Явное намерение не захватывать или не собирать результат для других сотрудников

API UIKit оказывается позади, не добавляя @discardableResult для совершенно нормального (если не более общего) использования popViewController(animated:) без записи возвращаемого значения.

Подробнее

  • 15
    Это (на мой взгляд) , безусловно, шаг назад от Swift 2, особенно , когда есть такие методы , как это , что, несмотря на то, что они делают возвращают значение, то совершенно правомерный прецеденты , когда вы просто не использовать его.
  • 15
    1. Вам не нужен let : вы можете просто присвоить _ без предшествующего ему let или var .
Показать ещё 14 комментариев
36

Когда жизнь дает вам лимоны, сделайте расширение:

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 тоже.

  • 0
    Это должно быть принятым решением, так как это самое чистое исправление того, что обязательно будет исправлено в обновлении XCode.
23

В Swift 3 игнорирование возвращаемого значения функции с объявленным возвращаемым значением приводит к предупреждению.

Один из способов отказаться от этого - отметить функцию атрибутом @discardableResult. Поскольку у вас нет контроля над этой функцией, это не сработает.

Другой способ избавиться от предупреждения - присвоить значение _. Это говорит компилятору, что метод возвращает значение, но вы не хотите его сохранять в памяти.

let _ = navigationController?.popViewController(animated: true)
  • 2
    Я думаю, нам придется придерживаться уродливого _ пока Apple не обновит UIKit с этим новым атрибутом.
  • 2
    К сожалению, @discardableResult не работает (по крайней мере, он все еще квакает с 8b4). Фридрих Шиллер любил гнилые яблоки. Наверное, дело вкуса :-(
4

Изображение 1748

Хотя он work correctly if kept as it is, но number of warning increases.

Решение - просто replace it with underscore ( _ ), хотя оно кажется уродливым.

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

Изображение 1749

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

Другой способ - вы можете развернуть значение self.navigationController? и вызвать функцию popViewController.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню