Digamos que tengo tres objetos administrados diferentes. Cada tipo de objeto tiene propiedades idénticas. Me gustaría escribir un método que acepte cualquiera de los tres objetos y asigne valores a sus propiedades.
let car = Car(context: context) let boat = Boat(context: context) let plane = Plane(context: context) getDistanceTraveled(vehicle: car) func getDistanceTraveled(vehicle: NSManagedObject) { let newVehicle = vehicle as? Car //Instead of Car I want to cast this as the type being passed in. newVehicle.distanceTraveled = 43 }
Por lo general, siguiendo el principio de reutilización compuesta (composición sobre herencia), sugeriría usar un protocolo para un problema como este, por ejemplo
protocol Vehicle { var distanceTraveled: Float { get set } } struct Car: Vehicle { var distanceTraveled: Float } struct Boat: Vehicle { var distanceTraveled: Float }
Luego pase un Vehicle
a su función:
func getDistanceTravelled(vehicle: Vehicle) -> Float { return vehicle.distanceTraveled }
Sin embargo, creo que esto es más complejo que lo descrito anteriormente, ya que los objetos Car
, Boat
y Plane
son administrados por Core Data y son una subclase de NSManagedObject
.
Si bien hay formas de lidiar con esto, por ejemplo,
En su lugar, sugeriría crear una entidad principal de Vehicle
en Datos básicos que contenga las propiedades compartidas, y luego hacer que Vehicle
sea la entidad principal de sus otras entidades, automóvil, avión, etc.
p.ej
Captura de pantalla de la entidad vehicular
Captura de pantalla de la entidad del coche
Captura de pantalla de entidad plana
Luego puede pasar un objeto administrado Vehicle
a su función de la siguiente manera:
func getDistanceTravelled(vehicle: Vehicle) -> Float { return vehicle.distanceTraveled }
Esto va en contra del principio de reutilización compuesta mencionado anteriormente, pero creo que debido a la naturaleza de los datos centrales, este podría ser uno de esos escenarios en los que gana la herencia.
Una solución NSManagedObject
es una extensión de protocolo restringida a NSManagedObject
protocol TravelDistance { var distanceTraveled: Float { get } } extension TravelDistance where Self : NSManagedObject { func getDistanceTravelled(vehicle: TravelDistance) -> Float { return vehicle.distanceTraveled } }
Todas las subclases de NSManagedObject
que se ajustan a TravelDistance
pueden usar este método.