Reutilizando una subclass UIViewController que hice para situaciones muy similares pero no idénticas: ¿recomendadas?

Todavía soy relativamente nuevo en el desarrollo de iOS y me preguntaba si es una buena práctica hacer eso.

Por ejemplo, digamos que tengo dos contexts diferentes en los que quiero presentar datos idénticos / similares en forms idénticas / similares, pero hay algunas diferencias, tal vez algunos botones diferentes de un context a otro o diferentes cosas que necesito hacer para preparar los datos. ¿Debo hacer varios methods de configuration en el mismo controller de vista y llamar al que sea necesario, o tener dos controlleres de vista separados?

Estoy muy inclinado hacia que el primero sea correcto, ya que parece mucho más eficiente y guarda muchos códigos idénticos, pero me gustaría recibir información de progtwigdores más experimentados por las dudas.

Debe crear tres controlleres de vista: SuperViewController , FirstViewController y SecondViewController . FirstViewController y SecondViewController deberían ser las subclasss de su SuperViewController . Entonces debes considerar lo siguiente:

Variables y properties

Declare todas las variables comunes entre sus controlleres de vista en SuperViewController .

Declare las variables y properties específicas del controller de vista dentro del controller de vista apropiado.

Métodos

Al igual que con las properties, defina cualquier método compartido en su SuperViewController junto con su implementación.

Si tiene methods que comparten algunos, pero no todos sus códigos entre sus controlleres de vista, haga lo siguiente:

1) En su SuperViewController implementar este método:

 -(void)someSemiShanetworkingMethod { // put the common code here } 

2) En sus controlleres de vista:

 -(void)someSemiShanetworkingMethod { // call the superclass' implementation of this method // to ensure that common code is executed [super someSemiShanetworkingMethod]; // now add any child controller specific code to this method below } 

Esto se adapta como el mejor enfoque para lo que quieres lograr. Avíseme si tiene alguna otra pregunta o si este enfoque no alcanza completamente lo que desea.

Puede hacer el método de superclass padre que describió Andriy, pero hay otra opción.

Subclasificar es muy poderoso, pero a veces es difícil de razonar. Si hay un error en uno de los controlleres de vista secundarios, puede ser difícil determinar dónde realmente se encuentra ese error.

Si las personalizaciones para el controller de vista son pequeñas, puede express esto usando arguments para el constructor, por ejemplo:

 - (instancetype)initWithSaveButton(BOOL)includeSaveButton; 

O, si necesita personalizar algún comportamiento, pase un bloque:

 - (instancetype)initWithSaveAction:(void (^)(Person *))saveAction; 

Si las personalizaciones son mínimas, creo que es una solución más clara que la subsorting.


EDIT : Una nota lateral, pero @leiyun hizo una gran pregunta sobre las banderas BOOL, ¿y si queremos elegir entre include el button A y el button B? ¿Debemos diseñar un método init como este?

 - (instancetype)initWithButtonA:(BOOL)includeA buttonB:(BOOL)includeB; 

Bueno, este es un gran ejemplo de por qué las banderas BOOL deben evitarse. Si llamamos a este método como initWithButtonA:YES buttonB:YES , estamos en un comportamiento indefinido porque queríamos elegir entre esos botones.

Entonces, para esto, defina un tipo de opciones.

 typedef enum { MyViewControllerModeNoButtons, MyViewControllerModeButtonA, MyViewControllerModeButtonB } MyViewControllerMode; - (instancetype)initWithMode:(MyViewControllerMode)mode; 

Un principio rector para interfaces como esta es que no debería haber una forma incorrecta de llamarlo. Además, esto mejor acomodará más opciones cuando necesite un tercer button o una vista de image o algo más.

Para completar, también quiero presentar lo que consideraré como una tercera opción después de las respuestas de Andriy y Joerick, especialmente para las " cosas diferentes que necesito hacer para preparar los datos " -escenario: en realidad, utilizo la misma class de controller de vista para ambos pantallas, pero creando objects fuente de datos separados para cada context que contienen, preparan y proporcionan los datos apropiados.

Esos objects fuente de datos podrían ser subclasss NSObject simples, que se ajustan a un protocolo. Para forms comunes de mostrar datos, ya existen protocolos pnetworkingefinidos para fonts de datos, como UITableViewDataSource y UICollectionViewDataSource . Si esos no se adaptan a sus necesidades, por supuesto, puede definir su propio protocolo. La fuente de datos podría ser retenida por una instancia de controller de vista como una propiedad, así:

 @property (strong, nonatomic) id<UITableViewDataSource> myDataSource; 

Podría "entregar" la fuente de datos apropiada a su controller de vista al inicializarse, por ejemplo,

 -(instancetype)initWithDataSource: (id<UITableViewDataSource>) dataSource