(Also, NB, Swift3 needs a “!” On p.next: unfortunately, I don’t know exactly why.)
Since .next returns an optional parameter, but p is not optional. This will crash if you run out of respondents.
1) It seems ... dangerous ... to change General to General.self - is it actually safe and has the same meaning as General in Swift <3?
I am surprised to have worked in earlier versions of Swift without .self , but yes, .self is required to refer directly to the metatype. Linking to metatypes is somewhat rare in Swift and can lead to unexpected behavior if it is done unintentionally, so it requires an extra piece of syntax to say "yes, I really mean the type."
why is this a metatype? “I did something wrong” and asked for a metatep, not just a type?
You did it right.
2) What the hell is this "metatype"?
Type of type. An example of a metatype is a type. Consider:
func f(x: Int)
To call this, you pass an instance of Int . Similar:
func f<T>(x: T.Type)
To call this, you pass in an instance of the T.Type meta tag, which is a type.
Unrelated, but I would probably change my mind about this code in these lines. Firstly, it’s convenient to be able to consider the chain of respondents as a sequence. Here is one way to do this:
public extension UIResponder { public func nextResponders() -> AnySequence<UIResponder> { guard let first = next else { return AnySequence([]) } return AnySequence(sequence(first: first, next: { $0.next })) } }
Then, getting the next responder that matches the type is a cleaner and more understandable IMO (and works in any response chain):
public extension UIResponder { public func firstResponder<T: UIResponder>(ofType _: T.Type)-> T? { return nextResponders() .flatMap { $0 as? T } .first } } ... self.firstResponder(ofType: General.self)?.clickedHamburgerMenuButton()