我执行URLSession.shared.downloadTask
请求,但是想在执行downloadTask
的同一个线程上执行代码。例如:
func sample() {
let thread = Thread.current
URLSession.shared.downloadTask(with: file) {
someFunc() //How to execute on thread variable?
}.resume()
}
在downloadTask
完成处理程序中,它在后台线程上运行。但是,我想在调用同一个帖子someFunc()
上调用sample()
。我如何做Thread.current.async {...}
这样的事情,所以我可以这样做:
func sample() {
let thread = Thread.current
URLSession.shared.downloadTask(with: file) {
thread.async { someFunc() } //Doesn't compile
}.resume()
}
答案 0 :(得分:2)
如果您想在特定Thread
上投放某些内容,则不会使用此GCD API,而只是:
perform(#selector(someMethod), on: thread, with: nil, waitUntilDone: false, modes: [RunLoopMode.commonModes.rawValue])
当然,假设您创建了一个带有运行循环的线程,例如:
let thread = Thread(target: self, selector: #selector(threadEntryPoint), object: nil)
thread.start()
和
func threadEntryPoint() {
autoreleasepool {
Thread.current.name = "com.domain.app.background"
let runLoop = RunLoop.current
runLoop.add(NSMachPort(), forMode: .defaultRunLoopMode)
runLoop.run()
}
}
有关详细信息,请参阅Threading Programming Guide。
就个人而言,如果人性化,我个人会留在GCD内,但你在别处说过,你有一些独特的要求可以排除这种情况。
答案 1 :(得分:0)
没有像Thread.current.async这样的东西就是它不能编译的原因。
如果您想在同一个帖子上投放sample
和someFunc
,可以使用Operation
和OperationQueue
。这种方法的缺点,你
阻止一个线程。
var myQueue:OperationQueue = {
let q = OperationQueue()
q.name = "downloadQueue"
// if you want to limit concurrent operation
q.maxConcurrentOperationCount = 5
return q
}()
class DowloadOperation :Operation {
enum State {
case Ready, Executing, Finished
// ...
}
var state = State.Ready {
willSet {
...
}
didSet {
...
}
}
override func start() {
if self.isCancelled {
state = .Finished
} else {
state = .Ready
main()
}
}
override var isFinished: Bool {
get {
return state == .Finished
}
}
override var isAsynchronous: Bool {
get {
return true
}
}
override var isExecuting: Bool {
get {
return state == .Executing
}
}
override func main() {
if self.isCancelled {
self.state == .Finished
return
}
state = .Executing
URLSession.shared.downloadTask(with: file) {
// ...
state = .Finished
}
}.resume()
}
}
func someFunc() {
...
}
// sample and someFunc are executed on the same thread
// you loose the advantage of the async download.
func sample() {
downloadOp = DownloadOperation()
myQueue.addOperation(downloadOp)
downloadOp.waitUntilFinished()
someFunc()
}