> Что такое селектор в iOS и как работает target-action? (iOS, Swift)

Уровень: junior · Роль: mobile · Категория: Технические вопросы

Компании: MTS

Стек: iOS, Swift

> Пример ответа

Короткий ответ

Селектор в iOS - это тип Selector, который инкапсулирует имя метода и используется для динамического вызова этого метода. Target-action - это паттерн, где один объект (target) хранит ссылку на метод (action), который нужно вызвать при наступлении события. В UIKit он реализуется через addTarget(_:action:for:), где селектор указывает, какой метод вызвать у target. Это основа работы кнопок, жестов и других UIControl.

Подробное объяснение

Селектор - это не сам метод, а его идентификатор. В Swift он создаётся через #selector(SomeClass.someMethod) или строку "someMethod:". Селектор не хранит информацию о типе аргументов - только имя и количество двоеточий. Это позволяет вызывать метод у любого объекта, у которого этот метод есть, без знания конкретного типа.

Target-action работает так: объект-источник события (например, UIButton) хранит слабую ссылку на target и селектор. При наступлении события (touch up inside) он вызывает perform(action, with: sender). Это динамическая диспетчеризация через Objective-C runtime, поэтому методы для селекторов должны быть доступны из Objective-C - помечены @objc или наследовать NSObject.

Важные детали:

  • Селектор может принимать от 0 до 2 параметров: action, action(_ sender:), action(_ sender:forEvent:).
  • Target хранится как weak, чтобы избежать retain cycle.
  • Один target может иметь несколько action-методов для разных событий.
  • Паттерн широко используется не только в UIControl, но и в UIGestureRecognizer, NSTimer, NotificationCenter.

На практике

В UIKit вы подписываетесь на событие кнопки так:

SWIFT
button.addTarget(self, action: #selector(handleTap), for: .touchUpInside)

При этом self - target, handleTap - action. Когда пользователь нажимает кнопку, UIKit вызывает handleTap у self.

Важно помнить, что селектор не проверяет сигнатуру метода на этапе компиляции - ошибка проявится только в рантайме, если метод не существует или имеет неверные параметры. Поэтому в Swift используют #selector с проверкой компилятором, а не строки.

Пример кода

SWIFT
class ViewController: UIViewController {
let button = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
button.addTarget(self, action: #selector(handleTap(_:)), for: .touchUpInside)
}
@objc func handleTap(_ sender: UIButton) {
print("Button tapped")
}
}

Как отвечать на собеседовании

Начните с определения селектора как ссылки на метод, затем объясните target-action как механизм связи события с методом. Упомяните, что target хранится слабо, а селектор - это строка или #selector. Приведите пример с кнопкой. Если спросят про альтернативы - скажите про closure и делегаты, но подчеркните, что target-action исторически используется в UIKit и поддерживает несколько событий у одного контрола.

Что проверяет интервьюер

  • Понимание разницы между селектором и обычным вызовом метода.
  • Знание, почему нужен @objc и как это связано с Objective-C runtime.
  • Понимание weak-ссылки на target и риска retain cycle.
  • Умение объяснить сигнатуры action-методов (0, 1 или 2 параметра).
  • Осознание, что селектор не типизирован и ошибки возникают в рантайме.

Типичные ошибки

  • Путать селектор с самим методом или с замыканием.
  • Забывать @objc - код не скомпилируется.
  • Использовать строку вместо #selector - теряется проверка компилятором.
  • Не учитывать, что target - weak, и пытаться хранить target сильно.
  • Пытаться передать в action-метод произвольные аргументы - селектор поддерживает только sender и event.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью