针对不同对象的多个领域查询

时间:2018-07-23 09:05:24

标签: swift polymorphism realm realm-mobile-platform

我想创建一个整个数据库搜索,该搜索返回一个类型为GetPermissions.Handler的对象。我有一个类Results<A>,它从一个领域A继承,然后还有许多其他类都从该子类继承。像这样:

Object

现在,我想同时查询不同的类,并且正在执行以下操作:

class A: Object {}
protocol Z {}
class B: A, Z {}
class C: A, Z {}
class D: A, Z {}
...

我这样称呼它:

private func getResults<T: A>(withTypes types: [T.Type]) {
  for type in types {
    let foundIds = getRealm().objects(type).filter(aPredicate)
    ids.append(contentsOf: foundIds)
  }

  // Do something with all those ids
}

问题是Realm不喜欢多态性,并且在我调用函数时在数组内添加多个类类型时,它会崩溃,因为数组的推断类型是getResults(withTypes: [B.self, C.self, D.self]) 而不是单个元素在数组的每个位置。过滤是通过使用A.self不符合的Z协议变量完成的,并且不应该这样做,但是其余对象确实符合它。如此有效:

A

或者这个:

getResults(withTypes: [C.self])

因为getResults(withTypes: [D.self]) 的推断类型是ArrayC.self,而不是普通的推断的D.self

我想指出的是,数据库中没有任何A.self对象,它只是所有其他对象的超类。

如何创建多个搜索?

我以为可以创建一种可搜索的对象并对其进行查询,但是我管理的数据库很大,我不知道这是否会对系统性能产生重大影响。

谢谢!

1 个答案:

答案 0 :(得分:1)

在查询中,如果您仅对获取ID并将其附加到数组感兴趣,则可以将其映射为ids.append(contentsOf: foundIds.map({ $0.idFromZProtocol }))。但这将禁用延迟加载Realm,因为将访问所有对象。

您还可以做另一种方式:

  • 假设A是动物,B是狗,C是鸟,D是猫。
  • 您正在寻找所有绿色动物。

你可以拥有

Animal
@objc dynamic var dog: Dog?
@objc dynamic var bird: Bird?
@objc dynamic var cat: Cat?

Bird, Cat, Dog
@objc dynamic var color: String
@objc dynamic var legNumber: Int

let predicate = "dog.color == Green || bird.color == Green || cat.color == Green"
getRealm().objects(Animal.self).filter(predicate)

您可以在Animal上使用一个经过处理的变量,通过检查哪个变量为nil来确定它是猫还是狗还是鸟。您也可以将Z协议分配给Dog,Cat和Bird,以便进行Animal.color而不是猜测Animal.dog?.colorAnimal.cat?.color

通过这种方法,您可以保留Realm的延迟加载功能,如果您有一个非常大的Realm文件,那就很好了。