es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Generalizando múltiples modelos de vista.

He escrito un par de modelos de vista para mi proyecto de SwiftUI. Resulta que comparten muchas propiedades y código, y quería extraer este código en un modelo de vista genérico y luego utilizar la herencia de clases para especializar los modelos de vista reales. Desafortunadamente, esto resulta bastante difícil. Aquí hay un ejemplo simplificado:

class viewModelA: ObservableObject {
    enum Animal {
        case cat
        case dog
    }

    @published var selected: Animal?

    func select(_ animal: Animal?) {
        self.selected = animal
    }
    ...
}

class viewModelB: ObservableObject {
    enum Animal {
        case lion
        case tiger
    }

    @published var selected: Animal?

    func select(_ animal: Animal?) {
        self.selected = animal
    }
    ...
}

Lo primero que he intentado es crear un protocolo y utilizar un protocolo con un typealias para Animal, pero luego tuve problemas con la propiedad que tiene “@published”. Swift no permite tener envolturas de propiedad en protocolos…

¿Cómo podría generalizar esas dos clases?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una posible solución es crear una clase genérica que tome el tipo animal asociado como su parámetro genérico. Esta clase contendría las propiedades y métodos compartidos entre los dos modelos de vista, mientras que los modelos de vista específicos (viewModelA y viewModelB en este caso) heredarían de la clase genérica y proporcionarían su propio tipo de animal.

    Aquí está el código para la clase genérica:

    class GenericViewModel<animaltype>: ObservableObject {
        @Published var selected: AnimalType?
    
        func select(_ animal: AnimalType?) {
            self.selected = animal
        }
        ...
    }
    

    Tenga en cuenta que AnimalType es el parámetro genérico que será reemplazado por el enum específico para cada modelo de vista.

    Ahora, los modelos de vista específicos pueden heredar de la clase GenericViewModel y proporcionar su propio tipo de animal:

    class viewModelA: GenericViewModel<animal> {
        enum Animal {
            case cat
            case dog
        }
    
        // no es necesario declarar @Published de nuevo ya que está en la clase padre
        // otras propiedades y métodos específicos para viewModelA ...
    }
    
    class viewModelB: GenericViewModel<animal2> {
        enum Animal2 {
            case lion
            case tiger
        }
    
        // no es necesario declarar @Published de nuevo ya que está en la clase padre
        // otras propiedades y métodos específicos para viewModelB ...
    }
    

    Tenga en cuenta que en los modelos de vista específicos, no es necesario declarar @Published de nuevo ya que ya está en la clase padre. Además, cada modelo de vista específico puede proporcionar sus propias propiedades y métodos adicionales específicos para su propio contexto.

    Este enfoque permite reutilizar el código y reduce la duplicación al tiempo que proporciona flexibilidad para cada modelo de vista específico.

Comments are closed.