【问题标题】:Conforming @MainActor class, or actor, to Codable使 @MainActor 类或演员符合 Codable
【发布时间】:2021-10-13 20:59:16
【问题描述】:

如何将 Codable 一致性添加到需要隔离到 MainActor 的类中?

例如,以下代码给出编译器错误:

@MainActor final class MyClass: Codable {
    var value: Int
    
    enum CodingKeys: String, CodingKey {
        case value
    }
    
    init(from decoder: Decoder) throws { // <-- Compiler error: Initializer 'init(from:)' isolated to global actor 'MainActor' can not satisfy corresponding requirement from protocol 'Decodable'
        let data = try decoder.container(keyedBy: CodingKeys.self)
        self.value = try data.decode(Int.self, forKey: .value)
    }
    
    func encode(to encoder: Encoder) throws { // <-- Compiler error: Instance method 'encode(to:)' isolated to global actor 'MainActor' can not satisfy corresponding requirement from protocol 'Encodable'
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(value, forKey: .value)
    }
}

我现在肯定很难理解演员和@MainActor!

【问题讨论】:

  • 我最初发布了一个我发现错误的答案 - 使 init(from decoder: Decoder) async 将允许 MyClass 符合 Decodable,但我无法得到 @987654326 @遵守工作。
  • 不,因为那些 async 函数与 Encodable 想要调用的函数不同。

标签: swift concurrency swiftui swift-concurrency


【解决方案1】:

您提供的类没有任何内容需要与主要参与者隔离,因此不要将整个类隔离。如果还有其他您没有向我们展示的成员确实需要与主要演员隔离,请隔离他们。

例子:

final class MyClass: Codable {
    private var value: Int
    @MainActor init(value: Int) {
        self.value = value
    }
    @MainActor func setMyValue(to newValue:Int) {
        self.value = newValue
    }
    @MainActor func getMyValue() -> Int {
        self.value
    }
    enum CodingKeys: String, CodingKey {
        case value
    }
    init(from decoder: Decoder) throws {
        let data = try decoder.container(keyedBy: CodingKeys.self)
        self.value = try data.decode(Int.self, forKey: .value)
    }
    func encode(to encoder: Encoder) throws { // <-- Compiler error: Instance method 'encode(to:)' isolated to global actor 'MainActor' can not satisfy corresponding requirement from protocol 'Encodable'
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(value, forKey: .value)
    }
}

【讨论】:

    猜你喜欢
    • 2022-06-14
    • 2022-08-21
    • 1970-01-01
    • 2018-07-12
    • 2018-02-22
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多