¿Puedo hacer que la class Realm Results utilice el protocolo como generics?

Quiero crear dos classs de models de Realm y un protocolo, que es adoptado por las dos classs de models. Por ejemplo:

class Dog: Object, Animal { dynamic var name = "" } class Cat: Object, Animal { dynamic var name = "" } protocol Animal { var name: String { get } } 

En este caso, creé dos classs model y un protocolo.

Sin embargo, cuando me mudé a la implementación, ocurrió el problema. El código a continuación está escrito en el controller de vista:

 var dogs: Results<Dog>? { return try! Realm().objects(Dog) } var cats: Results<Cat> { return try! Realm().objects(Cat) } 

Este código no tiene ningún problema. Pero el código a continuación:

 var animals: Results<Animal>? { switch currentSegmented { // this is from UISegmentedControl case .Cat: // this is from enum return self.cats case .Dog: return self.dogs } 

no se comstack con el error: los Results requires that Animal inherit from Object .

Sin embargo, Animal es un protocolo y, por lo tanto, no se puede henetworkingar de Object .

¿Todavía es posible utilizar el protocolo aquí?

Solutions Collecting From Web of "¿Puedo hacer que la class Realm Results utilice el protocolo como generics?"

No creo que haya una buena solución. Los generics definidos por el usuario en Swift son invariantes, por lo que incluso si Animal es una class, no puede convertir Results<Dog> a Results<Animal> .

La solución desagradablemente detallada es crear un tipo de contenedor explícito alnetworkingedor de sus diferentes types de resultados:

 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 ... } 

Puede crear este genérico al crear un contenedor semipesado para envolver Resultados:

 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))