运行循环将 交互式应用程序与命令行工具区分开来
。
- 使用参数启动命令行工具,执行命令,然后退出。
- 交互式应用程序等待用户输入,做出反应,然后继续等待。
从这里
它们使您可以等到用户点击并做出相应的响应,再等到获得completeHandler并应用其结果,再等到获得计时器并执行功能。如果没有运行循环,则无法监听/等待用户敲击,也无法等待网络通话发生,除非您使用DispatchSourceTimer
或,否则无法在x分钟之内唤醒DispatchWorkItem
也从这个评论:
后台线程没有自己的运行循环,但是您可以只添加一个。例如,AFNetworking 2.x做到了。对于后台线程上的NSURLConnection或NSTimer,这是一种经过实践检验的真正技术,但是由于更新的API消除了这样做的必要,因此我们不再自己这样做。但是似乎URLSession确实做到了,例如,这是简单的request,正在主队列上运行[请参见图像的左面板]完成处理程序,并且您可以看到它在后台线程上具有运行循环
特别是关于:“背景线程没有自己的运行循环”。以下计时器无法触发异步调度:
class T {
var timer: Timer?
func fireWithoutAnyQueue() {
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false, block: { _ in
print("without any queue") // success. It's being ran on main thread, since playgrounds begin running from main thread
})
}
func fireFromQueueAsnyc() {
let queue = DispatchQueue(label: "whatever")
queue.async {
self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false, block: { (_) in
print("from a queue — async") // failed to print
})
}
}
func fireFromQueueSnyc() {
let queue = DispatchQueue(label: "whatever")
queue.sync {
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false, block: { (_) in
print("from a queue — sync") // success. Weird. Read my possible explanation below
})
}
}
func fireFromMain() {
DispatchQueue.main.async {
self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false, block: { (_) in
print("from main queue — sync") //success
})
}
}
}
我认为该sync
块也运行的原因是:
同步块通常仅在其源队列中执行。在此示例中,源队列是主队列,任何队列都是目标队列。
为了测试我RunLoop.current
在每个调度中都登录了。
同步调度的运行循环与主队列相同。异步块中的RunLoop与其他实例不同。您可能在想为什么RunLoop.current
返回不同的值。这不是共享的价值吗?好问题!进一步阅读:
重要的提示:
在类属性 current
不是一个全局变量。
返回当前线程的运行循环。
它是上下文相关的。仅在线程范围内(即线程本地存储)可见。有关更多信息,请参见此处。
这是计时器的已知问题。如果使用,您不会遇到相同的问题DispatchSourceTimer