Trailing where cláusula de extensión de tipo no genérico

Tengo el siguiente código:

func registerNotification(name:String, selector:Selector) { NSNotificationCenter.defaultCenter().addObserver(self, selector: selector, name: name, object: nil) } func registerKeyboardNotifications() { let isInPopover = navigationController?.popoverPresentationController != nil let ignore = isInPopover && DEVICE_IS_IPAD if !ignore { registerNotification(UIKeyboardWillShowNotification, selector: Selector("keyboardWillShow:")) registerNotification(UIKeyboardWillHideNotification, selector: Selector("keyboardWillHide:")) } } 

en una extensión a UIViewController . Este código es reutilizado por muchos viewcontroller para registrarse en notifications de keyboard. Sin embargo, con Swift 2.2 produce una advertencia. Me gusta la nueva syntax #selector pero no estoy segura de cómo implementarla en este caso.

Creo que la solución correcta es hacer un protocolo y extender UIViewController solo para las instancias que se ajustan a ese protocolo. Mi código hasta ahora:

 @objc protocol KeyboardNotificationDelegate { func keyboardWillShow(notification: NSNotification) func keyboardWillHide(notification: NSNotification) } extension UIViewController where Self: KeyboardNotificationDelegate { func registerKeyboardNotifications() { let isInPopover = navigationController?.popoverPresentationController != nil let ignore = isInPopover && DEVICE_IS_IPAD if !ignore { registerNotification(UIKeyboardWillShowNotification, selector: #selector(KeyboardNotificationDelegate.keyboardWillShow(_:))) registerNotification(UIKeyboardWillHideNotification, selector: #selector(KeyboardNotificationDelegate.keyboardWillHide(_:))) } } } 

Sin embargo, esto me da el error

 trailing where clause for extension of non-generic type 

en la fila de extensión. ¿Algunas ideas?

La solución fue simple para cambiar el order en la cláusula de extensión:

 extension UIViewController where Self: KeyboardNotificationDelegate 

debiera ser

 extension KeyboardNotificationDelegate where Self: UIViewController 

extension Foo where ... solo se puede usar si Foo es

  1. una class o estructura genérica: se extiende con una implementación pnetworkingeterminada para generics que se ajustan a alguna restricción de tipo,
  2. un protocolo que contiene algunos types asociados, se extiende con una implementación pnetworkingeterminada para cuando un tipo asociado se ajusta a alguna restricción de tipo
  3. un protocolo en el que se extiende con una implementación pnetworkingeterminada para cuando Self es de un tipo específico (object / reference), o se ajusta a algún tipo de restricción.

P.ej

 // 1 class Foo<T> { } extension Foo where T: IntegerType {} struct Foz<T> {} extension Foz where T: IntegerType {} // 2 protocol Bar { associatedtype T } extension Bar where T: IntegerType {} // 3 protocol Baz {} extension Baz where Self: IntegerType {} class Bax<T>: Baz {} extension Baz where Self: Bax<Int> { func foo() { print("foo") } } let a = Bax<Int>() a.foo() // foo 

En su caso, UIViewController es un tipo de class no genérico, que no se ajusta a ninguno de los dos anteriores.


Como ha escrito en su propia respuesta, la solución es ampliar su protocolo de delegado con una implementación pnetworkingeterminada para los casos en los que Self: UIViewController , en lugar de intentar extender UIViewController .