为什么@Published属性会导致此错误:类型'Booking'不符合协议'Decodable'

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

我遇到了一个奇怪的问题。只需添加属性 @Published 就会导致此错误:“类型‘Booking’不符合协议‘Decodable’”

这编译得很好:

class Booking: ObservableObject, Codable {
    private (set) var module    : Module   
    private (set) var lecturer  : Lecturer? = nil
    
    init(withModul module : Module) {
        self.module = module
    }
}

此时出现错误:

class Booking: ObservableObject, Codable {
    private (set) var module : Module   
    @Published private (set) var lecturer : Lecturer? = nil

    init(withModul module : Module) {
        self.module = module
    }
}

当然,类型“Lecturer”和“Module”(结构体)都符合“Codable”及其所有属性。

以前从来没有遇到过这个问题,有什么建议。

swift combine codable
1个回答
1
投票

因为您已将

@Published
属性包装器添加到
lecturer
,所以该属性的类型现在是
Published<Lecturer>
而不是
Lecturer
Published
即使包裹起来也不符合
Codable
Value
符合
Codable

如果您不希望包装的属性成为编码/解码的一部分,您可以简单地从

Codable
一致性中省略它,方法是为
CodingKey
创建一个
Booking
一致枚举并省略
lecturer
属性在那里。

class Booking: ObservableObject, Codable {
    private (set) var module : Module
    @Published private (set) var lecturer : Lecturer? = nil

    init(withModul module : Module) {
        self.module = module
    }

    enum CodingKeys: String, CodingKey {
      case module
    }
}

或者,如果您确实想要编码/解码

lecturer
,您需要手动实现
Codable
一致性。

class Booking: ObservableObject, Codable {
  private (set) var module : Module
  @Published private (set) var lecturer : Lecturer? = nil

  init(withModul module : Module) {
    self.module = module
  }

  enum CodingKeys: String, CodingKey {
    case module
    case lecturer
  }

  required init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.lecturer = try container.decodeIfPresent(Lecturer.self, forKey: .lecturer)
    self.module = try container.decode(Module.self, forKey: .module)
  }

  func encode(to encoder: Encoder) throws {
    try lecturer?.encode(to: encoder)
    try module.encode(to: encoder)
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.