是什么决定了SWIFT 5.5任务初始值设定项是否在主线程上运行? [英] What determines whether a Swift 5.5 Task initializer runs on the main thread?

查看:0
本文介绍了是什么决定了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
        }
    }
}
test1test2这两个函数完全相同,并且是从完全相同的位置调用的。但其中一个在后台线程上运行其任务初始值设定项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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆