I am creating a doubly-linked-list of scripts (MSScript
s) that are supposed to have their own run()
implementation, and they call the next script (rscript
) when they're ready . One of the scripts I'd like to create is just a delay. It looks like this:
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
}
}
Where rscript
is the next script to run. The problem is that if I remove the last line of the dispatch_after, it doesn't compile, and that's because of the changed return type of run()
from optional chaining. I randomly decided to insert Void.self
and it fixed the problem, but I have no idea why.
What is this Void.self
, and is it the right solution?
Optional chaining wraps whatever the result of the right side is inside an optional. So if run()
returned T
, then x?.run()
returns T?
. Since run()
returns Void
(a.k.a. ()
), that means the whole optional chaining expression has type Void?
(or ()?
).
When a closure has only one line, the contents of that line is implicitly returned. So if you only have that one line, it is as if you wrote return weakSelf.rscript?.run()
. So you are returning type Void?
, but dispatch_async
needs a function that returns Void
. So they don't match.
One solution is to add another line that explicitly returns nothing:
dispatch_after(time, dispatch_get_main_queue()) {
weakSelf.rscript?.run()
return
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With