【问题标题】:Swift + Realm newbie: Problems with a simple Realm object and its initializersSwift + Realm 新手:一个简单的 Realm 对象及其初始化程序的问题
【发布时间】:2016-08-18 16:04:45
【问题描述】:

我是一名长期的 Objective-C 开发人员,几周前听说过 Realm。另一方面,我一直想一点一点地迁移到 Swift,所以我创建了一个涉及 Realm + Swift 的小项目。

这是什么意思?我是 Swift + Realm 新手。

无论如何,我为我想到的一个项目创建了一个小型演示/概念证明,我认为它必须更容易。但 Xcode 编译器另有说明。

我的问题在于我的对象的初始化程序之一。

我的意图很简单,但显然 Realm 需要比我想要的更多的初始化程序。

我的一个领域对象的代码是这样的:

import Foundation

import Realm
import RealmSwift

class Partida: Object
{
    dynamic var id_partida: String
    dynamic var inventario: Inventory?

    required init ()
    {
        inventario = Inventory()
        id_partida = "id_partida_test"
        super.init()
    }



    required init(value: AnyObject, schema: RLMSchema) {
        //fatalError("init(value:schema:) has not been implemented")
        super.init(value: value, schema: schema)
    }


    required init(realm: RLMRealm, schema: RLMObjectSchema) {
        //fatalError("init(realm:schema:) has not been implemented")
        super.init(realm: realm, schema: schema)
    }

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

}

我的原始代码只有“正常”的初始化程序。但是 Xcode 迫使我再创建两个额外的初始化程序(值和领域)。

如果我编译上面刚刚粘贴的代码,Xcode 会在第 2 和第 3 个必需的初始化程序中抱怨,特别是在 super.init 部分。 它说:

Property 'self.id_partida' not initialized at super.init call

我理解它的含义,但我不知道如何避免错误,因为如果我删除两个 super.init 行,程序会在运行时崩溃。

如果我取消注释 fatalError 行,它们也会在运行时崩溃。

事实上我不想使用这两个初始化器。如果可以,我不会添加它们,但显然 Xcode 需要添加它们。我真正想添加到我的对象初始化函数的唯一代码是“简单的”初始化函数,这是我认为的唯一代码部分。

我想我可能对 Realm + Swift + 初始化器有一些概念误解。

我也觉得 Xcode 强迫我添加我不需要和/或我也不理解的代码。

欢迎任何有关理解 Realm 中“必需的 init”初始化程序的帮助。

Realm + Swift 官方文档超出了我的知识范围,因为即使在多次重读之后,我也无法理解其中的许多概念。

这次 Google 和 StackOverflow 并没有真正提供帮助......

谢谢。

【问题讨论】:

  • 你只需要convenience init,里面加self.init(),不需要required init
  • 如果我注释掉“必需的 init”复杂初始化程序(第 2 和第 3 个),XCode 7.3 无论如何都会抱怨。它只是不编译。如果我在简单初始化程序之前删除“required”关键字,XCode 会抱怨:“你需要在所有覆盖上使用 required 关键字”。
  • 请查看下面的答案,希望对你有帮助

标签: ios xcode swift realm initializer


【解决方案1】:

Swift 中的初始化程序的行为肯定与 Objective-C 有点不同,所以我绝对可以看到你从这里来的角度。

但在这种情况下,由于您只是使用初始化程序来设置一些默认值,因此完全没有必要,因为您应该能够将默认值分配给属性本身:

class Partida: Object
{
    dynamic var id_partida = "id_partida_test"
    dynamic var inventario: Inventory? = Inventory()

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

}

如果这仍然不起作用,请告诉我! :)

【讨论】:

  • 确实如此,我的最终代码版本真的被剥离了,就像你输入的那样 :) 无论如何,我担心一旦我需要额外的初始化程序,或者我的对象变得更复杂(他们会的),我将来需要额外的帮助来解决这个意想不到的困难话题。谢谢
【解决方案2】:

因为它在Object 类中已经有init (),所以你正在使用Object 的子类,所以你在Realm 对象中已经有了它的init,你应该给你的var init 值,比如dynamic var id_partida: String = "id_partida_test",然后如果你调用 let test = Partida() 它已经有你的 2 init 值,其他 init 应该标记方便

当你将 Object 保存到持久化存储时,它应该总是有值的,你可以使用 Realm 的 optional 然后需要阅读文档

这是我的示例 Realm 类,以便您了解:

import Foundation
import RealmSwift
import SwiftyJSON

class ProjectModel: Object {
    dynamic var id: Int = 0
    dynamic var name: String = ""

    //Dont need this, call init() already have value
    required init() {
       id = 0
       name = ""
       super.init()
    }

    convenience init(fromJson json: JSON!){
        self.init()

        if json == nil {
            return
        }

        id = json["id"].intValue
        name = json["name"].stringValue
    }

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

【讨论】:

  • 我已将您的部分代码改编为我的。现在 XCode 编译器不会强迫我使用“必需的 init”复杂初始化程序,但是在便利 required init() 中使用 self.init() 会创建一个无限初始化程序循环(正如我在运行您的示例之前所期望的那样)并且它在运行时崩溃。我不明白在 init() 中调用 self.init() ...
  • 我认为你不需要那个 init :) 所以应该删除它并给你的变量起始值,如果你想创建支持者 init 则使用方便的 init
  • 好的,没有初始化,现在可以编译了。我现在必须在 var 声明中分配我的原始初始化值(没问题)。显然也没有崩溃,所以我必须检查我的领域对象属性是否被存储、持久化等......我感觉我没有 100% 明白为什么它现在可以工作。还是谢谢...
  • 因为你基本上是Object类的子类,并且它已经指定了init(所有类必须至少有1个)来构造Realm,所以你应该只使用convenience init来添加支持自定义初始化,我不确定 Realm 是如何工作的,但我通常是这样做的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-25
相关资源
最近更新 更多