ios - usar - signos de interrogacion y exclamacion para niños
Doble signo de interrogación, ¿Cómo funciona? (1)
El extra ?
se requiere que sourceViewController
devuelva un AnyObject
lugar de un UIViewController
. Esta es una falla en la conversión de API desde Objective-C (en la cual dicha propiedad devuelve un id
sin sentido). Sigue siendo un proceso en curso que comenzó con iOS 8 beta 5, y al parecer esas API aún no se han corregido.
Si proporciona un elenco apropiado, funcionará como se espera
(self.sourceViewController as UIViewController).presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
Ahora, ¿por qué necesitamos un extra ?
Cuando se trata de AnyObject
?
AnyObject
puede representar cualquier tipo de objeto, casi como lo hace id
en Objective-C
. Así que en tiempo de compilación puede invocar cualquier método existente en él, por ejemplo sourceViewController
.
Al hacerlo, se activa un AnyObject
implícito de AnyObject
a UIViewController
y de acuerdo con la guía oficial :
Al igual que con todos los downcasts en Swift, no se garantiza que la conversión de
AnyObject
a un tipo de objeto más específico tenga éxito y, por lo tanto, devuelve un valor opcional
Así que cuando lo hagas
self.sourceViewController.presentingViewController??
implícitamente se traduce en algo como
let source: UIViewController? = self.sourceViewController as? UIViewController
let presenting: UIViewController? = source?.presentingViewController
¿Y por eso necesitas dos ?
: uno para resolver el downcast y otro para la presentingViewController
.
Finalmente, siempre de acuerdo con la documentación:
Por supuesto, si está seguro del tipo de objeto (y sabe que no es nulo), puede forzar la invocación con el operador as.
que es exactamente mi solución propuesta anteriormente.
Estoy aprendiendo Swift y, como parte del proceso, tratando de averiguar qué es exactamente lo que está sucediendo aquí. Tengo un segmento personalizado donde quiero colocar la transición de cierre de mi controlador de vista modal. Lo que solía estar en objetivo-c como:
UIViewController *sourceViewController = self.sourceViewController;
[sourceViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];
self
es una instancia de UIStoryboardSegue
. Traduje este fragmento en Swift como:
self.sourceViewController.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
Obteniendo este error del compilador:
''UIViewController?'' no tiene un miembro llamado ''dismissViewControllerAnimated''
Ahora, por documentación , el método presentingViewController
se ve así:
var presentingViewController: UIViewController? { get }
De lo que entendí por la documentación del lenguaje Swift,? debe desenvolver el valor, en su caso. En este caso el controlador de vista. El hecho no explicado es: si pongo un doble signo de interrogación, se compila y funciona:
self.sourceViewController.presentingViewController??.dismissViewControllerAnimated(true, completion: nil)
¿Puede alguien decirme lo que me estoy perdiendo? ¿Qué debería hacer eso?