运行循环是 分隔 交互式应用的
命令行工具。
- 使用参数启动命令行工具,执行它们的命令,然后退出。
- 交互式应用等待用户输入,做出反应,然后继续等待。
来自here
它们允许你等到用户点击并做出相应的响应,等到你得到一个completionHandler并应用它的结果,等到你得到一个计时器并执行一个功能。如果你没有运行循环,那么你不能监听/等待用户点击,你不能等到网络调用发生,你不能在 x 分钟内被唤醒,除非你使用 DispatchSourceTimer 或 @ 987654329@
同样来自this comment:
后台线程没有自己的运行循环,但你可以添加
一。例如。 AFNetworking 2.x 做到了。这是经过尝试和真正的技术
NSURLConnection 或 NSTimer 在后台线程上,但我们不这样做
我们自己不再需要了,因为更新的 API 消除了这样做的需要。但
似乎 URLSession 确实,例如,here is simple request,正在运行 [参见图像的左侧面板]
主队列上的完成处理程序,您可以看到它已运行
在后台线程上循环
特别是:“后台线程没有自己的运行循环”。 async 调度无法触发以下计时器:
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 块也运行的原因是:
sync 块通常只是从它们的 source 队列中执行。在此示例中,源队列是主队列,whatever 队列是目标队列。
为了测试我在每次调度中都记录了RunLoop.current。
同步调度与主队列有 same 运行循环。而异步块中的 RunLoop 是与其他实例不同的实例。您可能会想为什么RunLoop.current 会返回不同的值。这不是一个共享值吗!?好问题!进一步阅读:
重要提示:
类属性 current 不是全局变量。
返回当前线程的运行循环。
这是上下文相关的。它仅在线程范围内可见,即Thread-local storage。有关更多信息,请参阅here。
这是定时器的一个已知问题。如果您使用DispatchSourceTimer,则不会遇到同样的问题