【问题标题】:Realm - list of objects in an object (Swift 3)领域 - 对象中的对象列表(Swift 3)
【发布时间】:2017-09-04 12:15:19
【问题描述】:

我有一个这样定义的模型类:

class BaseModel: Object {
    var data: JSON = JSON.null

    convenience init(_ data: JSON) {
        self.init()
        self.data = data
    }

    override static func ignoredProperties() -> [String] {
        return ["data"]
    }
}

class RecipeModel: BaseModel {
    dynamic var title: String {
        get { return data["fields"]["title"].stringValue }
        set { self.title = newValue }
    }

    ... more vars ...

    var ingredients: List<IngredientsModel> {
        get {
            let ingredients = List<IngredientsModel>()

            for item in data["fields"]["ingredients"] {
                ingredients.append(IngredientsModel(item.1))
            }

            return ingredients
        }
        set { self.ingredients = newValue }
    }
}

class IngredientsModel: BaseModel {
    dynamic var text: String {
        get { return data["text"].stringValue }
        set { self.text = newValue }
    }

    ... more vars ...
}

我想像这样使用它:

Api.shared.fetchAllEntries().call(onSuccess: {response in
        print(response.json)

        let realm = try! Realm()
        try! realm.write {
            realm.deleteAll()
        }

        for item in response.json["items"].arrayValue {
            let recipe = RecipeModel(item)
            try! realm.write {
                realm.add(recipe)
            }
        }
    }, onError: {
        print("error")
    })

所以基本上这个想法是将整个 JSON 传递给初始的 RecipeModel 类,它应该将其解析出来并在 Realm 数据库中创建我需要的对象。除了IngredientsModel 的嵌套列表外,它工作得很好。它们不会被添加到领域数据库中。

我认为潜在的问题是我在convenience init 中调用self.data 之前调用了self.init(),但我看不到任何解决此问题的方法。你们知道我怎样才能实现IngredientsModel 的内容设置正确,我会在RecipeModel 中有一个成分列表吗?

【问题讨论】:

  • 如果你想在数据库中有List,它应该是let ingredients: List&lt;IngredientsModel&gt;,没有任何自定义的getter/setter。
  • @user28434 感谢您的回答 - 是的,这可能会起作用,但是我将无法直接在变量本身中设置列表的内容,而是通过附加对象在视图控制器中的某个位置到 RecipeModel 对象,这对我来说似乎有点奇怪。真的没有办法为列表变量自定义 getter 吗?

标签: ios swift swift3 realm


【解决方案1】:

您当前的实现不起作用,因为您没有在RecipeModelinit 方法中调用ingredients 的getter/setter,因此IngredientsModel 实例永远不会在Realm 中持久化。

此外,将计算属性用作一对多关系(领域列表)是一个非常糟糕的主意,尤其是当您在该属性的 getter 中解析结果时。每次调用 ingredients 的 getter 时,您都会创建新的模型对象,而不仅仅是访问已经存储在 Realm 中的现有模型对象,但您永远不会删除旧的模型对象。如果您实际上将 IngredientsModel 实例保存到 Realm(如上所述,您目前没有这样做),您会看到您的数据库中充满了重复的条目。

你的整个方法似乎真的不是最理想的。您不应将未解析的 data 对象存储在模型类中并使用计算属性来解析它。您应该在初始化模型时对其进行解析,并且根本不应该存储未解析的数据。您可以使用 ObjectMapper 库直接从 JSON 响应中创建领域对象。

【讨论】:

  • 有道理,谢谢,我会试试ObjectMapper 看看效果如何。
  • 不用担心,很高兴我能帮上忙。
最近更新 更多