是什么决定了SWIFT 5.5任务初始值设定项是否在主线程上运行? [英] What determines whether a Swift 5.5 Task initializer runs on the main thread?
本文介绍了是什么决定了SWIFT 5.5任务初始值设定项是否在主线程上运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
这是我之前asyncDetached falling back into main thread after MainActor call的后续内容。
以下是iOS视图控制器的完整代码:
import UIKit
func test1() {
print("test1", Thread.isMainThread) // true
Task {
print("test1 task", Thread.isMainThread) // false
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
test1()
test2()
}
func test2() {
print("test2", Thread.isMainThread) // true
Task {
print("test2 task", Thread.isMainThread) // true
}
}
}
test1
和test2
这两个函数完全相同,并且是从完全相同的位置调用的。但其中一个在后台线程上运行其任务初始值设定项operation:
函数,另一个在主线程上运行。
是什么决定了这一点?我只能认为这与方法声明的位置有关。但是这和声明方法的位置有什么关系?
推荐答案
我认为规则必须是MainActor方法中的任务初始值设定项在主线程上运行。
,默认情况下,视图控制器的所有方法都是MainActor方法;另外,我观察到,如果我将test2
声明为nonisolated
,它的任务操作将在后台线程而不是主线程上运行。
我的猜测是,这是任务初始值设定项的操作继承其上下文的规则的一个示例:
test2
是MainActor方法;它在主线程上运行,因此任务操作继承。但
test1
没有为任何特殊线程标记。test1
本身在主线程上运行,因为它在主线程上被调用;但它没有被标记为在主线程上运行。因此,它的任务操作退回到在后台线程上运行。
无论如何,这是我的理论,但我感到奇怪的是,这一规则在相关的WWDC视频中没有明确阐述。
此外,Eventest2
在某种程度上只是一个MainActor方法。如果它是真正的MainActor方法,则在没有await
的情况下无法从后台线程调用它。但您可以,如此版本的代码所示:
func test1() {
print("test1", Thread.isMainThread) // true
Task {
print("test1 task", Thread.isMainThread) // false
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
test1()
Task.detached {
self.test2()
}
}
func test2() {
print("test2", Thread.isMainThread) // false
Task {
print("test2 task", Thread.isMainThread) // true
}
}
}
我发现这真的很奇怪,而且我很难阐明什么规则将管理这种无情的上下文切换行为,所以我不认为事情已经解决。
这篇关于是什么决定了SWIFT 5.5任务初始值设定项是否在主线程上运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文