import Dispatch
import Foundation
DispatchQueue.main.async {
print("just print in main async")
}
RunLoop.current.run(mode: .default, before: .distantFuture)
print("RunLoop.current.run ends!")
字符串
的数据
如果runLoop在打印“just print inmain async”后结束,是否意味着runLoop被main.async终止(就像UI事件一样)?
我想知道这个案子到底发生了什么。
2条答案
按热度按时间798qvoo81#
你问:
为什么
DispatchQueue.main.async
可以用作RunLoop.current.run
的输入源?你描述的行为并不一定意味着
DispatchQueue.main.async {…}
在技术上是runloop的“输入源”。它只意味着run(mode:before:)
可以允许libDispatch在返回之前运行已调度的项。我们无法获得这些实施细节。如果runLoop在打印“just print in main async”后结束,是否[意味着runloop]被
main.async
终止(就像UI事件一样)?不一定。以下是一些观察结果:
run(before:mode:)
返回时,它不会“终止”,而是它只运行一次循环。这只是一个在返回之前是否运行调度的块的问题。@IBAction
还是viewDidLoad
中这样做的)。这使得我更加不愿意对实现细节做出实质性的假设。print
替换为“兴趣点”路标):字符串
有时候我得到了:
x1c 0d1x的数据
其他时候我得到:
的
无可否认,前一种行为很难再现。但种族往往很难显现。
我的底线是,我会犹豫是否将“runloop输入源”一词与调度到队列的项目一起使用(没有看到RunLoop源代码或苹果的一些正式保证)。GCD和runloops是非常不同的技术堆栈/模式。我们通常会使用GCD(或者Swift并发或者其他类似的东西)来代替runloop模式。此外,我会犹豫是否依赖
RunLoop.current.run
来从调度队列中排出排队的项目。GCD在很大程度上消除了对传统运行循环
run
(反)模式的需要。如果这个问题纯粹是出于好奇,那么希望上面的内容能提供一些有用的观察结果。但是,如果引入runloop是为了在GCD中实现某些功能行为,我可能建议就这个更广泛的问题单独提出一个问题,并避免在混合中引入RunLoop
。gc0ot86w2#
是的,我认为在提供的代码中,由于
DispatchQueue.main.async
块,运行循环将在打印“just print in main async”后结束。As run循环将简单地无限期地等待事件(直到事件发生,因为您提供了
.distantFuture
)。在某个时刻,会发生事件,该事件可以是用户交互事件(UI事件)或正在处理的另一个源。此事件将中断运行循环,并允许调度的
DispatchQueue.main.async
块在主队列上执行。然后将从异步执行的块中打印“just print in main async”。
然而,在打印的语句之后,没有更多的事件被安排,因此run循环最终将退出并打印“RunLoop.current.run ends!”。
希望这个链接也有帮助。