使用 @MainActor 属性作为默认值进行初始化的选项

问题描述 投票:0回答:1

我有一个类,到目前为止在初始化期间使用

UIApplication.shared
作为默认参数。它的简化版本:

final class MyClass {
    private var application: UIApplication
    
    init(application: UIApplication = UIApplication.shared) {
        self.application = application
    }
}

使用

Strict Concurrency Checking
选项现在会出现以下错误:

无法引用主要参与者隔离类属性“共享” 来自非孤立的环境

这是有道理的,因为
Complete

被标记为

UIApplication
因此,它的所有属性都是异步的:
@MainActor

我看到了两种解决方案:

#解决方案1

将该属性标记为可选,并在

@available(iOS 2.0, *) @MainActor open class UIApplication : UIResponder { open class var shared: UIApplication { get } ... }

期间对其进行初始化。在某些情况下,这似乎是一个好主意,但这样我们就失去了依赖注入属性并使其可测试的能力。当我们知道属性确实已初始化时,进一步使用选项也会让人感到不舒服:

init

#解决方案2

让调用者负责初始化

final class MyClass { private var application: UIApplication? @MainActor init() { self.application = UIApplication.shared } }

上的类:

@Mainactor

第二个解决方案似乎工作得很好,但是我需要做一些重构工作,以便所有调用者都在 
final class MyClass { private var application: UIApplication init(application: UIApplication) { self.application = application } // Just to present what the caller would do @MainActor func option1ToInit() { _ = MyClass(application: UIApplication.shared) } // Just to present what the caller would do func option2ToInit() { Task { _ = await MyClass(application: UIApplication.shared) } } }

上执行。我想知道我是否还缺少其他选择。

    

swift concurrency
1个回答
3
投票
@MainActor

添加到 init (从您的描述来看似乎可以),那么您只需要将

@MainActor
的访问移至 init 即可:
.shared

更新:
SE-0411

修复了此限制。您可以使用即将推出的功能IsolatedDefaultValues 在 Swift 5.10 中启用它。

© www.soinside.com 2019 - 2024. All rights reserved.