/ Swift

Swift: Selector Syntax Sugar (Перевод)

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

За последние 12 месяцев мне посчастливилось работать со Swift примерно на 98,2% моей рабочей недели. За это время я научился создавать некоторые (по-моему) действительно красивые стили кода, которыми я сегодня поделюсь с вами.

1. Selectors
До Swift 2.2 селекторы были строковыми литералами и подвержены ошибкам, потому что мы, как люди, изобретали и все еще вносили свой вклад в опечатки всякий раз, когда давали возможность написать что-то без автозаполнения.

let button = UIButton(type: .system)
button.addTarget(self, action: Selector(“buttonTapped:”), for: .touchUpInside)
...
func buttonTapped(sender: UIButton) {
}

Одним из хороших соглашений об именах для вызовов ваших функций должно быть имя объекта, суффиксное с действием. В этом случае мы использовали объект кнопки, который приравнивается к buttonTapped:. Также помните, чтобы всегда передавать отправителю правильный тип в качестве первого и единственного аргумента, потому что лучше иметь его и не нуждаться в нем, чем нуждаться в нем и не иметь его.

Несколько других примеров того, как мне нравится называть соответствующие функции взаимодействия с пользователем:

func segmentedControlValueChanged(sender: UISegmentedControl) { }
func barButtonItemTapped(sender: UIBarButtonItem) { }
func keyboardWillShowNotification(notification: Notification) { }

2. Улучшения в Swift 2.2
Тем не менее, наши селекторы теперь намного безопаснее в Swift 2.2, но все же
U-G-L-Y (у него нет алиби). Все эти селекторы ухудшают ваш код и его сложно читать. Что делать, если у вас есть Massive View Controller? Что делать, если вы используете один и тот же селектор несколько раз?

button.addTarget(self, action:  
    #selector(ViewController.buttonTapped(_:)), for: .touchUpInside)

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

fileprivate struct Action {
    static let buttonTapped = 
        #selector(ViewController.buttonTapped(_:))
}
...
button.addTarget(self, action: Action.buttonTapped,       
    for: .touchUpInside)

Потрясающе. Теперь у нас есть одно место, чтобы включить все наши селекторы, и каждый объект, который хочет использовать этот селектор, получает его значение от статической константы внутри структуры Action. Мы должны использовать имя Action, потому что это лучшее, что есть в Selector, потому что селектор выбирается классом Selector (очевидно).

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

Это fileprivate, потому что мы не хотим, чтобы Xcode представлял нам ошибки с конфликтом «redeclaration», поэтому эта структура доступна только для этого файла .swift.

Я на самом деле использовал это в течение нескольких месяцев, и это хорошо послужило мне для этого времени. Но сегодня утром я понял, что могу принять это еще больше, и сделать его более ... сладким. Зачем создавать структуру Action, когда мы можем сделать расширение Selector?

fileprivate extension Selector {
    static let buttonTapped = 
        #selector(ViewController.buttonTapped(_:))
}
...
button.addTarget(self, action: .buttonTapped, for: .touchUpInside)

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

Мы также воспользовались выводами типа Swift's. По скольку этот метод ожидает объект Selector для аргумента action:, мы можем опустить префикс Selector полностью при передаче значения.

Это похоже на то, что вы выбираете цвет для UIColor и устанавливаете его в представлении:

view.backgroundColor = .black

Автор: Andyy Hope
Ссылка на статью: Swift: Selector Syntax Sugar