Подтвердить что ты не робот

Swift хочет, чтобы аргумент #selector подвергался воздействию Objective-C

У меня есть проект Swift, где я хочу привязать метод к событию крана UIButton. У меня есть следующий код:

class MyClass {
  let myButton = UIButton(frame: CGRectMake(50, 50, 100, 50))
  init() {
    myButton.addTarget(self, #selector(self.didTap(_:)), forControlEvents: .TouchUpInside)
  }

  func didTap(sender: UIButton) {
    print("Tapped")
  }
}

XCode выделяет мою строку addTarget и говорит:

Argument of '#selector' refers to a method that is not exposed to Objective-C

Если я добавлю префикс @objc к моему func didTap, как он предлагает, все будет хорошо.

У меня что-то включено в моих настройках сборки, что вызывает это странное поведение?

PS. Я получаю это поведение в 7.3.1. Но если я попробую это в 7.2.1, он не примет синтаксис #selector(method(_:)), а Selector("method:") отлично работает.

4b9b3361

Ответ 1

Селекторы - это функция Objective-C и могут использоваться только с методами, которые подвергаются динамической среде выполнения Obj-C. Вы не можете выбрать селектор для чистого метода Swift.

Если ваш класс наследует от NSObject, то его общедоступные методы автоматически отображаются в Obj-C. Так как ваш класс не наследует от NSObject, вам нужно использовать атрибут @objc, чтобы указать, что вы хотите, чтобы этот метод подвергался Obj-C, чтобы его можно было вызвать с помощью селектора Obj-C.

#selector() - новый синтаксис в Swift 2.2. Это позволяет компилятору проверить, что селектор, который вы пытаетесь использовать, фактически существует. Старый синтаксис устарел и будет удален в Swift 3.0.

Ответ 2

Если я добавлю префикс @objc к своему func didTap, как он предлагает, все будет хорошо.

У меня что-то включено в моих настройках сборки, что вызывает это странное поведение?

Нет. То, что вы видите, нормально. Селекторы - это функция Objective-C, и поэтому используется селектор для отправки сообщения в экземпляр класса. Единственный способ Objective-C может отправить это сообщение, если он может видеть ваш класс или сам метод. MyClass сам по себе не получен из NSObject, поэтому Objective-C не может его видеть. Поэтому, если вы не хотите выводить его из NSObject, вам по крайней мере нужно выставить метод Objective-C, пометив его @objc.

и Selector ( "method:" ) отлично работает

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

Ответ 3

У вас должен быть подкласс от NSObject