O que é @selector() em Swift e para que serve?
Se você já trabalhou com Objective-C ou se deparou com código legado, provavelmente já ouviu falar da construção mágica @selector(). Em Swift, ela se transformou em #selector, mas a essência permanece a mesma: é uma ponte entre a tipagem estática do Swift e a natureza dinâmica do runtime do Objective-C.
Imagine que você precisa passar uma referência a um método como argumento. Por exemplo, para tratar o clique de um botão ou se inscrever em notificações. Em Swift, estamos acostumados a usar closures, mas as bibliotecas da Apple (UIKit, AppKit, Foundation) ainda dependem do bom e velho mecanismo de seletores. É aqui que o @selector() em Swift se torna uma ferramenta indispensável.
Neste guia, abordaremos:
- Como declarar seletores corretamente no Swift moderno
- Erros típicos e como evitá-los
- Exemplos reais do desenvolvimento iOS
- Quando usar
#selectore quando usar alternativas
De @selector() a #selector: evolução da sintaxe
Em Objective-C, o seletor se parece com isto:
[@selector(buttonTapped:)]No Swift 2.0, surgiu a construção #selector, que se tornou o padrão. Veja como fica agora:
#selector(MyClass.buttonTapped(_:))A diferença principal: #selector em Swift é verificado pelo compilador. Se você digitar errado o nome do método ou passar uma assinatura incorreta, o compilador emitirá um erro. Isso é uma grande vantagem em relação ao Objective-C, onde o seletor é apenas uma string e o erro só aparece em tempo de execução.
Regras para declarar métodos para #selector
O método que você passa para #selector deve ser:
- Acessível a partir do Objective-C — marcado com o atributo
@objc - Não privado (ou marcado como
@objc private) - Compatível em assinatura com o que a parte chamadora espera
Exemplo de declaração correta:
class ViewController: UIViewController { @objc func buttonTapped(_ sender: UIButton) { print("Botão pressionado!") } override func viewDidLoad() { super.viewDidLoad() let button = UIButton(type: .system) button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside) }}Observe o @objc antes do método. Sem ele, o compilador não permitirá o uso de #selector.
@selector() Swift: exemplos práticos
1. Target-Action: botões e gestos
O cenário mais comum de uso do #selector é a vinculação de ações a elementos de UI:
class ProfileViewController: UIViewController { @objc private func avatarTapped(_ gesture: UITapGestureRecognizer) { print("Avatar pressionado") } @objc private func settingsButtonPressed() { print("Abrir configurações") } override func viewDidLoad() { super.viewDidLoad() // Gesto let tapGesture = UITapGestureRecognizer(target: self, action: #selector(avatarTapped(_:))) avatarImageView.addGestureRecognizer(tapGesture) // Botão settingsButton.addTarget(self, action: #selector(settingsButtonPressed), for: .touchUpInside) }}Lembre-se: se o método aceitar um parâmetro (por exemplo, UITapGestureRecognizer), você deve indicar _ na assinatura do seletor: #selector(avatarTapped(_:)).
2. PerformSelector e chamadas adiadas
Às vezes, é necessário chamar um método dinamicamente, especialmente ao trabalhar com KVO ou timers:
class TimerManager { @objc func fireTimer() {