Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
376 views
in Technique[技术] by (71.8m points)

ios - Optional chaining in Swift Closure where return type has to be Void

I am creating a doubly-linked-list of scripts (MSScripts) 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...