尝试异步捕获

Luc*_*nzo 4 try-catch swift

我有这些方法:

open func promptNow() throws {
    // show an alert view
}

open func promptAfter(dalay: TimeInterval) throws {
    try self.promptNow()
}
Run Code Online (Sandbox Code Playgroud)

这段代码编译得很好,但显然我需要调用try self.promptNow()异步块,例如:

open func promptAfter(dalay: TimeInterval) throws {
    let dispatchTime = DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
    queue.asyncAfter(deadline: dispatchTime) {
       try self.promptNow()  
    }
}
Run Code Online (Sandbox Code Playgroud)

这会产生错误:

从投掷类型() - > throws()到非投掷函数类型() - > Void的转换无效

我该如何解决这个问题?

Dáv*_*tor 5

您不能使异步函数可抛出,因为此函数的调用者将在调用异步方法后立即继续执行,因此无法捕获异步方法返回后将引发的错误.

您可以指定函数将闭包作为输入参数,并使该闭包可抛出或处理函数内部的错误而不是重新抛出它.

下面的所有代码都是用Swift3编写的.我已经使用该main线程执行,promptNow因为如果您正在呈现警报控制器,则需要在主线程上进行.

可抛出的闭包解决方案(因为您实际上并没有使用闭包来返回任何值,我不建议使用此解决方案):

open func promptAfter(delay: TimeInterval, completion: @escaping (_ inner: () throws -> Void) -> Void) {
    DispatchQueue.main.asyncAfter(deadline: .now()+delay) {
        do {
            try self.promptNow()
            completion({})
        } catch {
            completion({throw error})
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你这样称呼它:

promptAfter(delay: 5, completion: { inner in
    do {
        try inner()
    } catch {
        print(error)
    }
})
Run Code Online (Sandbox Code Playgroud)

处理内部错误的解决方案promptAfter:

open func promptAfter(delay: TimeInterval) {
    DispatchQueue.main.asyncAfter(deadline: .now()+delay) {
        do {
            try self.promptNow()
        } catch {
            print(error)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)