如何在线程实例上执行块?
How to execute block on thread instance?
我执行 URLSession.shared.downloadTask
请求,但想在执行 downloadTask
的同一线程上执行代码。例如:
func sample() {
let thread = Thread.current
URLSession.shared.downloadTask(with: file) {
someFunc() //How to execute on thread variable?
}.resume()
}
在 downloadTask
完成处理程序中,它是 运行 在后台线程上。但是,我想在调用 sample()
的同一个线程上调用 someFunc()
。我该怎么做 Thread.current.async {...}
这样我才能做到这一点:
func sample() {
let thread = Thread.current
URLSession.shared.downloadTask(with: file) {
thread.async { someFunc() } //Doesn't compile
}.resume()
}
如果你想 运行 某个特定 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 中,但您在其他地方说过您有一些独特的要求,因此无法这样做。
没有什么比 Thread.current.async 这就是它无法编译的原因。
如果你想在同一个线程上 运行 sample
和 someFunc
,你可以使用 Operation
和 OperationQueue
。这种方法的缺点,你
ar 阻塞了一个线程。
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()
}
我执行 URLSession.shared.downloadTask
请求,但想在执行 downloadTask
的同一线程上执行代码。例如:
func sample() {
let thread = Thread.current
URLSession.shared.downloadTask(with: file) {
someFunc() //How to execute on thread variable?
}.resume()
}
在 downloadTask
完成处理程序中,它是 运行 在后台线程上。但是,我想在调用 sample()
的同一个线程上调用 someFunc()
。我该怎么做 Thread.current.async {...}
这样我才能做到这一点:
func sample() {
let thread = Thread.current
URLSession.shared.downloadTask(with: file) {
thread.async { someFunc() } //Doesn't compile
}.resume()
}
如果你想 运行 某个特定 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 中,但您在其他地方说过您有一些独特的要求,因此无法这样做。
没有什么比 Thread.current.async 这就是它无法编译的原因。
如果你想在同一个线程上 运行 sample
和 someFunc
,你可以使用 Operation
和 OperationQueue
。这种方法的缺点,你
ar 阻塞了一个线程。
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()
}