En Objective-C, es posible especificar una clase conforme a un protocolo como parámetro de método. Por ejemplo, podría tener un método que solo permita un UIViewController
que se ajuste a UITableViewDataSource
:
- (void)foo:(UIViewController<UITableViewDataSource> *)vc;
No puedo encontrar una manera de hacer esto en Swift (quizás aún no sea posible). Puede especificar varios protocolos usando func foo(obj: protocol<P1, P2>)
, pero ¿cómo se requiere que el objeto también sea de una clase en particular?
Respuestas:
Puede definir
foo
como una función genérica y usar restricciones de tipo para requerir tanto una clase como un protocolo.Rápido 4
Swift 3 (también funciona para Swift 4)
Swift 2
fuente
protocol<>
proporciona (peroprotocol<>
no puede contener tipos que no sean de protocolo).numberOfSectionsInTableView
porque es una función requerida enUITableViewDataSource
?numberOfSectionsInTableView:
es opcional, es posible que esté pensando entableView:numberOfRowsInSection:
.func foo<T: UIViewController>(vc:T) where T:UITableViewDataSource { ... }
En Swift 4 puedes lograr esto con el nuevo signo &:
fuente
La documentación del libro Swift sugiere que use restricciones de tipo con una cláusula where:
Esto garantiza que "inParam" es de tipo "SomeClass" con la condición de que también se adhiera a "SomeProtocol". Incluso tiene el poder de especificar múltiples cláusulas where delimitadas por una coma:
fuente
Con Swift 3, puede hacer lo siguiente:
fuente
¿Y de esta manera ?:
fuente
Rápido 5:
Entonces, esencialmente , la respuesta de Jeroen anterior.
fuente
Nota en septiembre de 2015 : esta fue una observación en los primeros días de Swift.
Parece imposible. Apple también tiene esta molestia en algunas de sus API. Aquí hay un ejemplo de una clase recién introducida en iOS 8 (a partir de la versión beta 5):
UIInputViewController
'stextDocumentProxy
propiedad:Definido en Objective-C como sigue:
y en Swift:
Enlace a la documentación de Apple: https://developer.apple.com/library/prerelease/iOS/documentation/UIKit/Reference/UIInputViewController_Class/index.html#//apple_ref/occ/instp/UIInputViewController/textDocumentProxy
fuente
var textDocumentProxy: UITextDocumentProxy! { get }
@protocol MyAwesomeCallbacks <NSObject>