在调度中包装完成处理程序的语法async
问题描述:
我有一个完成处理程序需要分配给属性,但我希望它异步执行。在调度中包装完成处理程序的语法async
如果我没有这个要求,我会写:
request.completionBlock = completionBlock
但因为我有这样的要求,我必须写这个
request.completionBlock = { response, error in
DispatchQueue.main.async {
completionBlock(response, error)
}
}
这似乎是多余的和未SWIFTY 。
是不是有一些更简单的语法?我想写点类似于
request.completionBlock = completionBlock.map(DispatchQueue.main.async)
我可以用这么简单的方式表达我的需求吗?
答
没有用于表达的内置语法,但您可以始终定义一个通用函数或运算符,以便沿这些行启用某些内容。
例如:
infix operator >
func ><T>(left:@escaping (T)->(), right:DispatchQueue) -> (T)->() {
return { input in
right.async { left(input) }
}
}
随着定义上述运营商定制,你的代码可以是:
request.completionBlock = completionBlock > DispatchQueue.main
我认为这是一般的感觉,你正在寻找。
答
您是否拥有request
类的控制权?如果不是,那么我认为你必须咬紧牙关,明确地调度自己(显然是好的,或者至少在python :-)),或者像丹尼尔霍尔所说的那样定义你自己的速记。
如果你确实有控制权,那么我认为建议你简单地改变你的request
类的API,以保证完成处理程序在主线程中被调用。毕竟处理程序应该是快速的,毕竟,这通常是你想要的。
答
这里是一个扩展
extension DispatchQueue {
func asyncClosure<T>(_ closure:@escaping (T) -> Void) -> (T) -> Void {
return {i in self.async {closure(i)}}
}
}
,可以让你做到这一点:
request.completionBlock = DispatchQueue.main.asyncClosure(completionBlock)
+0
这个答案也非常有用。我在你和丹尼尔霍尔之间犹豫了很久。最后,我选择将奖金授予丹尼尔。非常感谢替代品! – KPM
是'request'一个类型的实例,你可以改变,还是需要成为一个扩展/它的子类? – DavidA