【问题标题】:Issue with Model class of Realm领域模型类的问题
【发布时间】:2018-11-13 06:22:57
【问题描述】:

我正在浏览一个项目的一些模型类(正在使用领域)。这是一堂课……

@objcMembers class CommA: Object {
  dynamic var id = 0
  dynamic var recipientId = "0"
  dynamic var name: String?
  dynamic var picture: String?
  dynamic var unreadMessageCount = 0
  dynamic var lastMessage: MyMessage?

  override class func primaryKey() -> String? {
    return "id"
  }
}

这看起来很容易。一个定义了变量和主键的类.. 但是还有另一个类看起来像这样……

@objcMembers class CommB: Object, Codable {
  dynamic var id = "0"
  dynamic var name: String?
  dynamic var picture: String?
  dynamic var status: String?
  dynamic var lastSeen: String?
  dynamic var unreadMessageCount = 0
  dynamic var lastMessage: MyMessage?

  enum CodingKeys: String, CodingKey {
    case id = "UsrID"
    case name = "UserName"
    case picture = "UsrPicture"
    case status = "ChatStatus"
  }

  required init() {
    super.init()
  }

  required init(value: Any, schema: RLMSchema) {
    super.init(value: value, schema: schema)
  }

  required init(realm: RLMRealm, schema: RLMObjectSchema) {
    super.init(realm: realm, schema: schema)
  }

  convenience init(id: String, name: String, picture: String, status: String) {
    self.init()
    self.id = id
    self.name = name
    self.picture = picture
    self.status = status
  }

  convenience required init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    let id = try container.decode(String.self, forKey: .id)
    let name = try container.decode(String.self, forKey: .name)
    let picture = try container.decode(String.self, forKey: .picture)
    //let status = try container.decode(String.self, forKey: .status)
    self.init(id: id, name: name, picture: picture, status: "status")
  }

  func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(id, forKey: .id)
    try container.encode(name, forKey: .name)
    try container.encode(picture, forKey: .picture)
    try container.encode(status, forKey: .status)
  }

  override class func primaryKey() -> String? {
    return "id"
  }
}

这里我不明白为什么要使用enumrequired initconvenience required init 等...?

【问题讨论】:

  • 这更像是一个与领域无关的快速问题

标签: ios swift realm


【解决方案1】:

事实上,有些初始化器是多余的。您的代码可以缩短为

@objcMembers class CommB: Object, Codable {
    dynamic var id = "0"
    dynamic var name: String?
    dynamic var picture: String?
    dynamic var status: String?
    dynamic var lastSeen: String?
    dynamic var unreadMessageCount = 0
    dynamic var lastMessage: MyMessage?

    enum CodingKeys: String, CodingKey {
        case id = "UsrID"
        case name = "UserName"
        case picture = "UsrPicture"
        case status = "ChatStatus"
    }

    convenience init(id: String, name: String, picture: String, status: String) {
        self.init()
        self.id = id
        self.name = name
        self.picture = picture
        self.status = status
    }

    convenience required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let id = try container.decode(String.self, forKey: .id)
        let name = try container.decode(String.self, forKey: .name)
        let picture = try container.decode(String.self, forKey: .picture)
        //let status = try container.decode(String.self, forKey: .status)
        self.init(id: id, name: name, picture: picture, status: "status")
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(name, forKey: .name)
        try container.encode(picture, forKey: .picture)
        try container.encode(status, forKey: .status)
    }

    override class func primaryKey() -> String? {
        return "id"
    }
}

我已经删除了

  required init() {
    super.init()
  }

  required init(value: Any, schema: RLMSchema) {
    super.init(value: value, schema: schema)
  }

  required init(realm: RLMRealm, schema: RLMObjectSchema) {
    super.init(realm: realm, schema: schema)
  }

其他的都很重要。

CommB不仅是领域对象,还是Codable。它的作者想要自定义解码/编码行为,以便解码/编码器仅解码/编码idnamepicturestatus。为此,需要创建一个CodingKey 枚举,存储编码密钥。另外,convenience required init(from decoder: Decoder)func encode(to encoder: Encoder) 需要实现。

convenience init(id: String, name: String, picture: String, status: String) 初始化器之所以存在,是因为 init(from decoder: Decoder) 委托给它。

要详细了解Codable 的工作原理,请访问here

【讨论】:

  • 我认为如果他了解 Codable 是什么,他可能不会发布问题。除了这个很好的答案之外,我还建议 OP 阅读有关 Codables 和 inits 类型的信息。
  • 谢谢@Sweeper..但是编码/解码什么时候会发生...?在得到一个api调用的响应之后..?
  • @user308123 该类本身不进行编码。这是来自其他人编写的项目吗?如果是这种情况,您可以在项目中搜索JSONDecoderJSONEncoder。它们用于解码和编码对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多