Cómo convertir una matriz de UIViewControllers en una matriz de types de protocolo

Tengo un UITabBarController cuyos viewControllers implementan el protocolo Refreshable . ¿Cómo es posible que no pueda desenvolver la propiedad viewControllers del controller de la barra de viewControllers en una matriz del tipo Refreshable ?

 if let tabs = self.tabBarController.viewControllers as? [Refreshable] { // Some code tabs[0].refresh() // refresh() is a function in Refreshable } 

No hay errores de compilation, pero el código dentro del cierre if let nunca se ejecuta. ¿Cómo puedo hacer esto correctamente?

AÑADIR:

Esto funciona, pero no me gusta; siento que debería poder express esto como en el anterior.

 if let tabs = self.tabBarController.viewControllers as? [UIViewController] { if tabs[0] is Refreshable { (tabs[0] as! Refreshable).refresh() } } 

Si su matriz es [UIViewController] , no aceptará elementos con el tipo Refreshable , ya que otras classs arbitrarias podrían ajustarse a él, que no tienen las properties de UIViewController .

En otras palabras, Refreshable sí solo no es una promise lo suficientemente fuerte para su matriz, ya que no garantiza UIViewController instancias de UIViewController .

La expresión original solo funcionaría en una matriz, donde el tipo se especifica mediante el tipo de protocolo de la siguiente manera:

 // Suppose MyClass conforms to Refreshable let myArray: [Refreshable] = [ MyClass(), MyClass(), MyClass(), MyClass(), ] // Now you can use refresh() without problems for item in myArray { item.refresh() } 

Desafortunadamente, dado que está utilizando la propiedad en un controller de barra de tabs, me temo que esta no es una opción para usted. Una forma posible de asegurarse de que solo utiliza instancias, que se ajustan a Refreshable es Refreshable filtrar / asignar su matriz así:

 let items = myarray.filter({ $0 is Refreshable }).map({ return $0 as! Refreshable }) // items will be [Refreshable] for item in items { item.refresh() } 

Es importante tener en count aquí que, si utiliza los items ya items será del tipo [Refreshable] , ya no puede asumir que tiene properties de su class original (es decir, MyClass ), solo las que les otorga el protocolo (es decir, refresh() en este caso).

la propiedad viewControllers en el controller de la barra de tabs se declara como [AnyObject]? … entonces el tipo verifica as? [Refreshable] as? [Refreshable] no pasa. en su lugar, itera a través de los controlleres de vista y el tipo de verificación para cada uno de ellos:

 for viewController in self.tabBarController!.viewControllers! { if let refreshableTab = viewController as? Refreshable { refreshableTab.refresh() } } 

Terminando @ József Vesza gran respuesta, puedes hacer algo como:

 if let tabs = self.tabBarController.viewControllers as? [UIViewController], let refreshables = tabs.filter({ $0 is Refreshable }).map({ $0 as! Refreshable } { refreshables[0].refresh() }