没有一个 GCD 机制来检索当前的调度队列,以便您以后可以向它调度。 (很久以前,曾经有一种获取当前队列的方法,但在 iOS 7 中已被弃用,即便如此,它还是“仅推荐用于调试和记录目的。”)
如果你想在特定的调度队列上调用完成处理程序,我建议为方法提供一个显式的DispatchQueue 参数。下面,我将其默认为.main,但调用者可以随意覆盖它:
func perform(_ request: URLRequest, with data: Data, on queue: DispatchQueue = .main, completion: @escaping (Result<T, Error>) -> Void) {
let task = session.uploadTask(with: request, from: data) { data, response, error in
if let error = error {
queue.async {
completion(.failure(error))
}
}
...
}
...
}
我知道这并不是您正在寻找的,但它是一种让调用者指定将在哪个队列上调用您的闭包的简单方法。
如果您使用的是操作队列,您可以获取current 来确定当前的操作队列。如果有人这样做,就会在该操作队列上使用addOperation 以调用完成处理程序。
func perform(_ request: URLRequest, with data: Data, completion: @escaping (Result<T, Error>) -> Void) {
guard let queue = OperationQueue.current else {
fatalError("Must be called from operation queue")
}
let task = session.uploadTask(with: request, from: data) { data, response, error in
if let error = error {
queue.addOperation {
completion(.failure(error))
}
}
...
}
...
}
但是这种模式只有在调用者使用操作队列时才有效,而不是仅在使用调度队列时有效。出于这个原因,我仍然倾向于采用提供目标操作队列作为参数的模式:
func perform(_ request: URLRequest, with data: Data, on queue: OperationQueue = .main, completion: @escaping (Result<T, Error>) -> Void) {
let task = session.uploadTask(with: request, from: data) { data, response, error in
if let error = error {
queue.addOperation {
completion(.failure(error))
}
}
...
}
...
}