我想创建两个Realm模型类和一个协议(protocol),由两个模型类采用。例如:
class Dog: Object, Animal {
dynamic var name = ""
}
class Cat: Object, Animal {
dynamic var name = ""
}
protocol Animal {
var name: String { get }
}
在这种情况下,我创建了两个模型类和一个协议(protocol)。
但是,当我转到实现的时候,问题出现了。下面的代码是在 View Controller 中编写的:
var dogs: Results<Dog>? {
return try! Realm().objects(Dog)
}
var cats: Results<Cat> {
return try! Realm().objects(Cat)
}
这段代码没有任何问题。但是下面的代码:
var animals: Results<Animal>? {
switch currentSegmented { // this is from UISegmentedControl
case .Cat: // this is from enum
return self.cats
case .Dog:
return self.dogs
}
未编译时出现错误:Results requires Animal inherit from Object
。
但是,Animal
是一个协议(protocol),因此不能从 Object
继承。
这里还可以使用协议(protocol)吗?
最佳答案
我认为没有好的解决方案。 Swift 中用户定义的泛型是不变的,所以即使 Animal
是一个你不能转换的类 Results<Dog>
至 Results<Animal>
.
令人不愉快的冗长解决方案是围绕您的不同类型的结果创建一个显式包装器类型:
enum AnimalResultsEnum {
case DogResults(dogs: Results<Dog>)
case CatResults(cats: Results<Cat>)
}
class AnimalResults {
var animals = AnimalResultsEnum.DogResults(dogs: try! Realm().objects(Dog))
var realm: Realm? {
switch animals {
case .DogResults(let dogs):
return dogs.realm
case .CatResults(let cats):
return cats.realm
}
}
var count: Int {
switch animals {
case .DogResults(let dogs):
return dogs.count
case .CatResults(let cats):
return cats.count
}
}
subscript(index: Int) -> Animal {
switch animals {
case .DogResults(let dogs):
return dogs[index]
case .CatResults(let cats):
return cats[index]
}
}
// ... wrap the rest of the methods needed ...
}
您可以通过创建一个半类型删除的容器来包装结果来使其通用:
class CovariantResults<T: Object> {
private var base: _CovariantResultsBase<T>
init<U: Object>(_ inner: Results<U>) {
base = _CovariantResultsImpl<T, U>(inner)
}
subscript(index: Int) -> T {
return base[index]
}
// ... wrap the rest of the methods needed ...
}
class _CovariantResultsBase<T: Object> {
subscript(index: Int) -> T { fatalError("abstract") }
// ... wrap the rest of the methods needed ...
}
class _CovariantResultsImpl<T: Object, U: Object>: _CovariantResultsBase<T> {
private let impl: Results<U>
init(_ inner: Results<U>) {
impl = inner
}
override subscript(index: Int) -> T {
return impl[index] as! T
}
// ... wrap the rest of the methods needed ...
}
// Used as:
let animals = CovariantResults<Animal>(try! Realm().objects(Dog))
关于ios - 我可以让 Realm Results 类使用协议(protocol)作为泛型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34172375/