Вызов метода протокола приводит к сбою

#ios #swift4

#iOS #swift4

Вопрос:

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

 protocol Testable where Self : UIView{
    func update()
}

class JKD : UIView,Testable{
    func update() {
        print("JKD")
    }
}

func test(a : Testable){
    a.update()
}

let j2 : JKD = JKD.init(frame: CGRect.zero)
test(a: j2) // it will crash 
  

И этот сбой можно исправить множеством способов, вот так :

 @objc protocol Testable where Self : UIView{
    func update()
}
  

или это :

 protocol Testable{
    func update()
}
  

и если функция использует Generic, это также может исправить сбой

 func test<T : Testable>(a : T) {
    a.update()
}
  

или, если класс в расширении наследует протокол, он также может исправить сбой.

 class JKD : UIView{}
extension JKD : Testable{
    func update() {
        print("JKD")
    }
}
  

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

Ответ №1:

Из примечаний к выпуску Swift 5,

Протоколы теперь могут ограничивать соответствующие им типы теми, которые относятся к подклассу данного класса. Поддерживаются две эквивалентные формы:

 protocol MyView: UIView { /*...*/ }
protocol MyView where Self: UIView { /*...*/ } 
  

Swift 4.2 принял вторую форму, но она не была реализована полностью
и иногда может произойти сбой во время компиляции или выполнения. (SR-5581)
(38077232)

Похоже, что они исправили существующие проблемы в Swift 5. Он отлично работает в Xcode 10.2 beta 4.