Почему использование неявной развертки или принудительной развертки, позволяющей сбою приложения на каком-то этапе, не выгодно?

Я хочу сказать, что в некоторых местах мы знаем, что переменная вообще не будет иметь nil, но по какой-то причине мы не можем создать ее экземпляр в функции инициализации класса, поэтому мы должны сделать ее необязательной.

Я также знаю, что мы можем использовать необязательные методы связывания или защиты, чтобы легко избавиться от него.

Но, по моему мнению, разработчикам на этапе разработки выгодно допускать сбой приложения из-за действительно глупых ошибок из-за неявной развертки/принудительной развертки.

Мой пример:

class TopStoriesViewModelTests: XCTestCase {
    var viewModel: TopStoriesViewModel!

    override func setUp() {
        super.setUp()
        viewModel = TopStoriesViewModel(interactor: MockTopStoriesInteractor())
    }

    func testArticleDidVisited() {
        viewModel.visited = xxxxxx
    }
}

В этом случае я могу сделать TopStoriesViewModel ?, а затем охранять его или разрешить его в каждом тестовом случае, но я чувствую, что это не обязательно. Я знаю, что тоже могу использовать viewModel?.xxx. Но дело не в этом.

Мой вопрос в том, прав ли я в том, что в некоторых определенных обстоятельствах, таких как пример, который я привел, полезно иметь принудительно развернутое/неявно развернутое.


person Tony Lin    schedule 15.06.2018    source источник
comment
@MortezaSoleimani - Просто неправда. Есть много случаев, когда вам нужно определить что-то, что не может быть установлено во время инициализации, но для чего, как вы знаете, никогда не должно быть nil, когда вы на самом деле собираетесь его использовать (розетки - один из многих примеров). И, что еще более важно, я видел тонны ужасного кода от нубов, которые беспечно проверяют необязательные параметры и просто return, если они nil, тем самым затрудняя диагностику проблем. И если вы собираетесь сделать что-то вроде вызова fatalError, когда необязательным было nil, когда этого не должно быть, то вы точно так же сделаете принудительную распаковку.   -  person Rob    schedule 15.06.2018


Ответы (1)


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

Типичным примером является доступ к изображению из пакета ресурсов. Строка типа:

let imagePath = Bundle.main.path(forResource: "image", ofType: "png")!

должен падать на ранней стадии разработки, если разработчик забыл правильно указать image.png. После правильного нацеливания эта строка не сломается, поэтому нет причин иметь дело с необязательным путем.

Другими распространенными примерами являются розетки. Обычно их делают неявно развернутыми, потому что к тому времени, когда они будут использоваться в коде контроллера представления, они уже будут прикреплены. Сбой, вероятно, означает, что розетка была подключена неправильно. Это исправляется, и больше не о чем беспокоиться. Нет необходимости иметь дело с охранниками или другими необязательными проверками.

Последний пример (есть еще много возможностей). При исключении ячейки из очереди из табличного представления принудительно преобразовать полученную ячейку в пользовательский тип ячейки. Нет необходимости в охране. Я все время вижу здесь код, который использует защиту с as? для выдачи фатальной ошибки в случае сбоя приведения. Просто принудительное литье. Вы получаете тот же сбой с меньшим количеством кода. Как только представление таблицы и раскадровка будут правильными, принудительное приведение не завершится ошибкой.

Сказав это, новым разработчикам Swift следует некоторое время избегать символа ! на своей клавиатуре. Знание того, когда безопасно использовать его, является приобретенным навыком.

Если потенциальный сбой полностью находится под контролем разработчика и сбой может произойти только из-за ошибки разработчика, то использование ! может быть уместным.

Если потенциальный сбой может быть вызван неожиданными данными (разбор JSON, пользовательский ввод и т. д.), никогда не используйте !. В таких случаях используйте защитный код.

tl; dr - да, есть много случаев, когда принудительное развертывание, принудительное приведение и неявно развернутые переменные являются правильным выбором.

person rmaddy    schedule 15.06.2018