gpt4 book ai didi

swift - 什么决定了 Swift 5.5 Task 初始值设定项是否在主线程上运行?

转载 作者:行者123 更新时间:2023-12-04 14:06:46 25 4
gpt4 key购买 nike

这是我之前 asyncDetached falling back into main thread after MainActor call 的后续.
这是 iOS View Controller 的完整代码:

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
}
}
}
两个函数 test1test2是相同的,并且是从同一个地方调用的。然而,其中一个运行它的 Task 初始值设定项 operation:在后台线程上运行,另一个在主线程上运行。
这是什么决定的?我只能认为它与声明方法的位置有关。但是它与方法在哪里声明有什么关系呢?

最佳答案

我认为规则必须是 MainActor 方法中的 Task 初始值设定项在主线程上运行。
并且 View Controller 的所有方法默认都是 MainActor 方法;另外,我注意到如果我声明 test2成为 nonisolated ,它的 Task 操作在后台线程而不是主线程上运行。
那么,我的猜测是,这是任务初始化程序的操作从其上下文“继承”规则的一个示例:

  • test2是一个 MainActor 方法;它在主线程上运行,因此任务操作“继承”了它。
  • 但是test1未标记任何特殊线程。 test1本身在主线程上运行,因为它是在主线程上调用的;但它没有被标记为在主线程上运行。因此,它的 Task 操作回退到在后台线程上运行。

  • 无论如何,这就是我的理论,但我觉得奇怪的是,相关的 WWDC 视频中没有明确阐明这条规则。
    而且,即使 test2只是一种“弱”方式的 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 - 什么决定了 Swift 5.5 Task 初始值设定项是否在主线程上运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67954414/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com