【问题标题】:Class has No Initializers Error Realm Class Swift类没有初始化器错误领域类 Swift
【发布时间】:2019-02-19 16:27:11
【问题描述】:

我得到一个 Class has no initializers 错误。这不是我设置课程的方式吗?这是一个领域对象数据库,我要存储的属性。我是 swift 和领域的新手,但我认为这就是它的完成方式。如果我取出 init() 函数并只分配它工作的所有值,但是诸如 justTook 之类的属性以及我不想以值开头的所有属性,我需要稍后在程序中设置它。

这是我的代码:

class MedInfo: Object {
    //  Info To Be Stored
    @objc dynamic var keyID = UUID().uuidString
    @objc dynamic var medName: String
    @objc dynamic var medDose: String
    @objc dynamic var currentDate: Date
    @objc dynamic var timeTook: Date
    @objc dynamic var lastTook: Date
    @objc dynamic var durationOfTime: Date
    @objc dynamic var doctorName: String
    @objc dynamic var rxDate: Date
    @objc dynamic var medInfo: String
    @objc dynamic var pictureOfMed: UIImage

    override static func primaryKey() -> String? {
        return "keyID"
    }

    convenience init(medName: String, medDose: String, currentDate: Date, timeTook: Date, lastTook: Date, durationOfTime: Date, doctorName: String,rxDate: Date, medInfo: String, pictureOfMed: UIImage) {
        self.medName = medName
        self.medDose = medDose
        self.currentDate = currentDate
        self.timeTook = timeTook
        self.lastTook = lastTook
        self.durationOfTime = durationOfTime
        self.doctorName = doctorName
        self.rxDate = rxDate
        self.medInfo = medInfo
        self.pictureOfMed = pictureOfMed
    }

【问题讨论】:

  • 如果您不想在初始化期间给变量赋值,可以将变量声明为可选项。

标签: swift realm


【解决方案1】:

您需要为所有参数设置默认值,如文档中模糊描述的那样。来自here

在 Swift 中使用 Realm 时,Swift.reflect(_:) 函数用于 确定有关您的模型的信息,这需要调用 init() 成功。 这意味着所有非可选属性必须具有 默认值。

所有示例都显示了这一点,因此请遵循它们。因此应该声明你的类:

class MedInfo: Object {
    //  Info To Be Stored
    @objc dynamic var keyID = UUID().uuidString
    @objc dynamic var medName: String = ""
    @objc dynamic var medDose: String = ""
    @objc dynamic var currentDate: Date = Date()
    @objc dynamic var timeTook: Date = Date()
    @objc dynamic var lastTook: Date = Date()
    @objc dynamic var durationOfTime: Date = Date()
    @objc dynamic var doctorName: String = ""
    @objc dynamic var rxDate: Date = Date()
    @objc dynamic var medInfo: String = ""

    // UIImage not supported, you'll need to store a URL/filename or something else
    @objc dynamic var pictureOfMed: UIImage

【讨论】:

    【解决方案2】:

    您必须调用 init 来创建实例。

    convenience init(medName: String, medDose: String, currentDate: Date, timeTook: Date, lastTook: Date, durationOfTime: Date, doctorName: String,rxDate: Date, medInfo: String, pictureOfMed: UIImage) {
    
        self.init() 
    
        self.medName = medName
        self.medDose = medDose
        self.currentDate = currentDate
        self.timeTook = timeTook
        self.lastTook = lastTook
        self.durationOfTime = durationOfTime
        self.doctorName = doctorName
        self.rxDate = rxDate
        self.medInfo = medInfo
        self.pictureOfMed = pictureOfMed
    }
    

    【讨论】:

      【解决方案3】:

      正如@ces 已经正确引用自 Realm 文档:“这意味着所有非可选属性都必须具有默认值。

      这就是为什么我认为创建 Realm 对象的最佳方法是将变量声明为可选项。

      这样您就不必调用 init。这是我创建自己的 Realm 对象的方式,也是我见过的大多数人创建它们的方式。

      所以你的对象应该是这样的:

      class MedInfo: Object {
      //  Info To Be Stored
      @objc dynamic var keyID = UUID().uuidString
      @objc dynamic var medName: String?
      @objc dynamic var medDose: String?
      @objc dynamic var currentDate: Date?
      @objc dynamic var timeTook: Date?
      @objc dynamic var lastTook: Date?
      @objc dynamic var durationOfTime: Date?
      @objc dynamic var doctorName: String?
      @objc dynamic var rxDate: Date?
      @objc dynamic var medInfo: String?
      @objc dynamic var pictureOfMed: UIImage?
      
      override static func primaryKey() -> String? {
          return "keyID"
      }
      

      【讨论】:

      • 您确实可以做到这一点。但是通过使您的模型属性成为可选的,您的模型属性现在是可选的。是的,我知道我在那里说了什么。但是现在,访问模型属性时,您将不得不处理它们为 nil 的可能性。如果它们可以为 nil 则可以,但如果这样做会削弱模型,则应该将它们设为可选。在示例中,我可以看到可能 pictureOfMed 是可选的(字符串),但所有其他字段都为 nil 是否有意义?
      • @ces 好吧,您当然是对的,使用非可选项更安全。但是正如 OP 所说,当他“只分配它工作的所有值时,但是像 justTook 这样的属性以及我不想要的所有东西都以一个值开头”。所以这就是为什么我认为在这种情况下使用选项更合适。他特别表示,他不想从默认值开始。当然,他必须将零值的风险计算到他的代码中。尽管 imo,您的回答仍然很好。