本文介绍: Swift 5.5 引入一个新的属性包装器 @MainActor,它提供了一种简单安全方式来在主线程执行代码

DispatchQueue.main.async

在Swift编写异步代码时,你可能会遇到一些并发性和线程安全性问题

例如刷新UI需要在主线程,在Swift 5.5之前我们都是使用手动来刷新主线程,这样既麻烦又容易遗漏

DispatchQueue.global().async {
    // 在后台线程执行耗时任务

    DispatchQueue.main.async {
        // 在主线程更新用户界面
    }
}

@MainActor

Swift 5.5 引入一个新的属性包装@MainActor,它提供了一种简单而安全的方式来在主线程上执行代码

@MainActor原理是,它将属性方法标记为只能在主队列主线程)上执行。这意味着使用 @MainActor 修饰代码块只能在主线程上运行,任何试图在其他线程上调用代码块的尝试都将被阻塞,直到在主线程上运行。

使用 @MainActor语法简单。你可以将它应用于属性方法示例代码如下

class MyViewController: UIViewController {
    @MainActor
    var data: [String] = []

    @MainActor
    func updateUI() {
        // 更新用户界面的代码
    }
}

在上面的代码中,data 属性updateUI() 方法都被标记@MainActor。这意味着任何试图在非主线程上修改 data 属性调用 updateUI() 方法尝试都将被阻塞,直到在主线程上执行

@MainActor可以用于函数参数,用于指示该参数必须在主线程上调用。例如:

@MainActor
func processUserInput(@MainActor completion: () -> Void) {
    // 处理用户输入的代码

    completion() // 在主线程上调用完成闭包
}

在上面的例子中,completion 参数标记@MainActor,这意味着传递给该函数闭包必须在主线程上调用

@MainActor标记过的代码,只会在主线程中执行,所以就不会有concurrency(并发)的问题

通过使用 @MainActor,你可以更轻松地确保你的代码在正确的线程上执行

在UIKit中使用@MainActor

现在我们看UIKit的API,都已经用@MainActor标记了。

我们在使用UIKit时,即便不用DispatchQueue.main.async,也能确保在主线程上执行

@MainActor open class UIButton : UIControl, NSCoding {} 

@MainActor open class UILabel : UIView, NSCoding, UIContentSizeCategoryAdjusting {}

@MainActor open class UIView : UIResponder, NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusItem, UIFocusItemContainer, CALayerDelegate {}

// more

 我们封装UIKit自定义控件时,为了保证线程安全,也需要@MainActor装饰

原文地址:https://blog.csdn.net/u010130947/article/details/131223845

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_19467.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注