En Swift puedo establecer explícitamente el tipo de una variable declarándola de la siguiente manera:
var object: TYPE_NAME
Si queremos dar un paso más y declarar una variable que se ajuste a múltiples protocolos, podemos usar el protocol
declarativo:
var object: protocol<ProtocolOne,ProtocolTwo>//etc
¿Qué sucede si me gustaría declarar un objeto que se ajusta a uno o más protocolos y también es de un tipo de clase base específico? El equivalente de Objective-C se vería así:
NSSomething<ABCProtocolOne,ABCProtocolTwo> * object = ...;
En Swift, esperaría que se vea así:
var object: TYPE_NAME,ProtocolOne//etc
Esto nos da la flexibilidad de poder lidiar con la implementación del tipo base, así como con la interfaz agregada definida en el protocolo.
¿Hay otra forma más obvia en la que podría estar perdiendo?
Ejemplo
Como ejemplo, digamos que tengo una UITableViewCell
fábrica que se encarga de devolver las células de acuerdo con un protocolo. Podemos configurar fácilmente una función genérica que devuelva celdas que se ajusten a un protocolo:
class CellFactory {
class func createCellForItem<T: UITableViewCell where T:MyProtocol >(item: SpecialItem,tableView: UITableView) -> T {
//etc
}
}
más adelante quiero quitar estas celdas mientras aprovecho tanto el tipo como el protocolo
var cell: MyProtocol = CellFactory.createCellForItem(somethingAtIndexPath) as UITableViewCell
Esto devuelve un error porque una celda de vista de tabla no se ajusta al protocolo ...
Me gustaría poder especificar que la celda es una UITableViewCell
y se ajusta a la MyProtocol
declaración de la variable.
Justificación
Si está familiarizado con Factory Pattern, esto tendría sentido en el contexto de poder devolver objetos de una clase en particular que implementan una determinada interfaz.
Al igual que en mi ejemplo, a veces nos gusta definir interfaces que tienen sentido cuando se aplican a un objeto en particular. Mi ejemplo de la celda de vista de tabla es una de esas justificaciones.
Si bien el tipo suministrado no se ajusta exactamente a la interfaz mencionada, el objeto que devuelve la fábrica sí lo hace y, por lo tanto, me gustaría la flexibilidad para interactuar tanto con el tipo de clase base como con la interfaz de protocolo declarada
NSSomething<ABCProtocolOne,ABCProtocolTwo> * object = ...;
. Este objeto parece bastante inútil porque NSSomething
ya sabe a qué se ajusta. Si no se ajusta a uno de los protocolos <>
, obtendrá unrecognised selector ...
bloqueos. Esto no proporciona ningún tipo de seguridad.