I am trying to migrate to using protocols instead of subclassing, but I still would like to be able to delegate up to the "super" implementation of a certain method before performing more specific logic. Below is the code I've written to demonstrate the functionality I want, but it's crashing. If this is for some reason a bad approach/missing the point of protocol oriented programming then I would love to learn why, but also right now I just need to know why this is crashing. Thanks!
import UIKit
protocol A where Self: UIView { }
extension A {
func method () {
print("protocol A")
}
}
protocol B: A { }
extension B {
func method () {
print("protocol B")
(self as A).method()
}
}
class X: UIView, B {
func method () {
print("class X")
(self as B).method()
}
}
This code is invoked simply by doing this:
let x = X()
x.method()
The code above crashes with an EXC_BAD_ACCESS at this line:
(self as A).method()
I have a partial answer, even though I still do not understand exactly what is going. I noticed that this crash was only occurring when I had the
where Self: UIView
constraint on protocol A. If I remove the constraint, no crash occurs. This made me think that somehow the object is losing its status as a UIView somewhere along the way, and that this is the problem. More specifically, it seems that when protocol B inherits from protocol A, it does not inherit the
where Self: UIView
clause, meaning that casting to B does not imply that the resulting entity is a UIView. Following this line of thinking, I was able to make the above code work by changing:
(self as B).method()
to
(self as B & UIView).method()
This seems like a bug to me, so I'm going to try to bring it to the attention of the Swift team.