主队列异步任务的执行顺序
Execution order of async tasks on the main queue
在下面的代码中,打印语句按照它们包含的数字(1、2、3 等)的顺序执行
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
print("4")
}
print("1")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
DispatchQueue.main.async {
print("5")
}
print("2")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
DispatchQueue.main.async {
print("6")
}
print("3")
}
你能解释一下为什么执行过程会这样吗?当我们在 viewDidLoad
中异步调度一个块时,viewWillAppear
和 viewWillAppear
方法是否已经在队列中?
Are viewWillAppear
and viewDidAppear
methods already in the queue when we asynchronously dispatch a block in viewDidLoad
?
实际上:是的。确切地说,它们不是 "in the queue",但它们已经作为现有主队列代码序列的一部分在训练中。
这完全取决于 运行 循环何时结束。在这种情况发生之前,您异步分派到主队列的代码不能 运行 。实际上,我们必须在 print 4
等发生之前完全结束此 CATransaction(运行 循环中的一个 "revolution")。
您可能已将此日志记录放入根视图控制器中。这是一种特殊情况,因为您的应用程序刚刚启动,在对 makeKeyAndVisible
的调用发送到 window.
之前没有任何反应
在那一刻,viewDidLoad
被调用,viewWillAppear
被连续调用,作为对 makeKeyAndVisible
.
的调用的一部分
因此,相同的代码仍在主线程上 运行ning;没有时间将您的代码发送到 运行。所以我们先得到 print 1
和 print 2
。
viewDidAppear
的情况有点不同:
如您所见,我们不再参与对 makeKeyAndVisible
的调用。但是主线程仍然是 运行ning,因为我们会立即转向任何事务完成块 (cleanUpAfterCAFlushAndRunDeferredBlocks
)。将 viewDidAppear
视为 viewWillAppear
中动画的有效完成块可能会有所帮助。这已经配置为调用 viewWillAppear
的一部分,因此它仍然是同一事务的一部分。因此 viewDidAppear
仍然紧跟在 viewWillAppear
之后,没有停顿,我们得到 print 3
.
现在 启动序列终于结束了,你的主队列异步代码有机会 运行,它按照它入队的顺序执行(print 4
, print 5
, print 6
).
在下面的代码中,打印语句按照它们包含的数字(1、2、3 等)的顺序执行
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
print("4")
}
print("1")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
DispatchQueue.main.async {
print("5")
}
print("2")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
DispatchQueue.main.async {
print("6")
}
print("3")
}
你能解释一下为什么执行过程会这样吗?当我们在 viewDidLoad
中异步调度一个块时,viewWillAppear
和 viewWillAppear
方法是否已经在队列中?
Are
viewWillAppear
andviewDidAppear
methods already in the queue when we asynchronously dispatch a block inviewDidLoad
?
实际上:是的。确切地说,它们不是 "in the queue",但它们已经作为现有主队列代码序列的一部分在训练中。
这完全取决于 运行 循环何时结束。在这种情况发生之前,您异步分派到主队列的代码不能 运行 。实际上,我们必须在 print 4
等发生之前完全结束此 CATransaction(运行 循环中的一个 "revolution")。
您可能已将此日志记录放入根视图控制器中。这是一种特殊情况,因为您的应用程序刚刚启动,在对 makeKeyAndVisible
的调用发送到 window.
在那一刻,viewDidLoad
被调用,viewWillAppear
被连续调用,作为对 makeKeyAndVisible
.
因此,相同的代码仍在主线程上 运行ning;没有时间将您的代码发送到 运行。所以我们先得到 print 1
和 print 2
。
viewDidAppear
的情况有点不同:
如您所见,我们不再参与对 makeKeyAndVisible
的调用。但是主线程仍然是 运行ning,因为我们会立即转向任何事务完成块 (cleanUpAfterCAFlushAndRunDeferredBlocks
)。将 viewDidAppear
视为 viewWillAppear
中动画的有效完成块可能会有所帮助。这已经配置为调用 viewWillAppear
的一部分,因此它仍然是同一事务的一部分。因此 viewDidAppear
仍然紧跟在 viewWillAppear
之后,没有停顿,我们得到 print 3
.
现在 启动序列终于结束了,你的主队列异步代码有机会 运行,它按照它入队的顺序执行(print 4
, print 5
, print 6
).