Encadenamiento opcional en Swift Closure donde el tipo de retorno tiene que ser Void

Estoy creando una list de scripts doblemente enlazada ( MSScript s) que se supone que tienen su propia implementación run() , y llaman al siguiente script ( rscript ) cuando están listos. Uno de los scripts que me gustaría crear es solo un retraso. Se parece a esto:

 class DelayScript : MSScript { var delay = 0.0 override func run() { let delay = self.delay * Double(NSEC_PER_SEC) let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay)) let weakSelf = self dispatch_after(time, dispatch_get_main_queue()) { weakSelf.rscript?.run() Void.self } } init(delay: Double) { super.init() self.delay = delay } } 

Donde rscript es el siguiente script para ejecutar. El problema es que si elimino la última línea del dispatch_after, no comstackrá, y eso se debe al tipo de retorno devuelto de run() desde el encadenamiento opcional . Al azar decidí insert Void.self y solucionó el problema, pero no tengo idea de por qué.

¿Qué es este Void.self y es la solución correcta?

El encadenamiento opcional envuelve cualquiera que sea el resultado del lado derecho dentro de un opcional. Entonces, si run() devuelve T , entonces x?.run() devuelve T? . Dado que run() devuelve Void (aka () ), eso significa que toda la expresión de encadenamiento opcional tiene el tipo Void? (o ()? ).

Cuando un cierre tiene una sola línea, el contenido de esa línea se devuelve implícitamente. Entonces, si solo tiene esa línea, es como si escribiera return weakSelf.rscript?.run() . ¿Entonces vuelves a escribir tipo Void? , pero dispatch_async necesita una function que devuelva Void . Entonces no coinciden.

Una solución es agregar otra línea que explícitamente no devuelva nada:

 dispatch_after(time, dispatch_get_main_queue()) { weakSelf.rscript?.run() return }