Category implementa un método que también se implementa en la class primaria: `viewWillAppear:`

Estoy intentando clasificar UIViewController para anular viewWillAppear: Pero recibiendo esta advertencia.

Category implementa un método que también se implementa en class primaria

 @implementation UIViewController (ViewWillAppearCategory) -(void)viewWillAppear:(BOOL)animated { //......... } @end 

Quiero hacer algunas cosas mientras la vista aparece en toda la pantalla, así que no quiero tocar en toda la pantalla . por eso, ve con categoría.

Puedo implementar algún método en la subclass y puedo llamar a ese método en todos los VC (toda la pantalla). Pero no quiero esto. Invocará automáticamente en la vista aparecerá la llamada. ¿Es esta una idea para hacer esto o cometió algún error en lo anterior?

Nota: Este código solo aparecerá en la fase de desarrollo para algún propósito de testing. Así que eliminaré este código cuando vaya con la tienda de aplicaciones. Por lo tanto, debería ser una tarea más fácil durante la eliminación, es decir, no tocaré toda la pantalla. No saveé este código durante el envío a la tienda de aplicaciones.

En tales casos, debe probar Method Swizzling, un concepto muy bien formado que le permite cambiar la implementación de un selector existente.

Para más detalles y código, visite el siguiente enlace.

http://nshipster.com/method-swizzling/

Las categorías son para agregar nuevos methods, no anular los existentes. Tal vez haga una subclass de UIViewController, digamos, MyUIViewController, con este código:

 -(void) viewWillAppear:(BOOL) animated { // do your "category" stuff } 

luego realice todas las demás subclasss de UIViewControllers de MyUIViewController con este código:

 -(void) viewWillAppear:(BOOL) animated { [super viewWillAppear:animated]; // rest of code for this class } 

Entiendo los motivos por los que desea tener una solución simple para probar algo en todas las pantallas y eliminarlo fácilmente, sin embargo:

  • No se puede llamar super en una categoría, y no llamar a [super viewWillAppear:] puede tener resultados inesperados dependiendo de la class y su implementación particular.
  • Los methods Swizzling son un truco y como lo eliminarás de tu versión final, tu versión de testing se volverá inútil ya que puede comportarse de manera muy diferente.

Por otro lado, crear una superclass UIViewController donde anular correctamente viewWillAppear: no es tan complicado:

  • El código pertenecerá solo a una sola class. No es necesario repetir / mantener el código para cada "pantalla".
  • Solo necesita cambiar una vez las references de la superclass de otros controlleres y Nibs o Storyboards.
  • Puede mantener la superclass para la testing y la liberación y el comportamiento será similar.
  • Puedes hacer muchas más cosas en una superclass que en una categoría.

En última instancia, sería interesante saber qué estás tratando de lograr. Probablemente podría lograr cosas similares mediante la implementación de un UINavigationControllerDelegate y realizar un seguimiento de los controlleres que se empujan y reventan.


En cuanto a la documentation de viewWillAppear :

Este método se invoca antes de que la vista del receptor esté a punto de agregarse a una jerarquía de vista y antes de que se configuren las animaciones para mostrar la vista. Puede anular este método para realizar tareas personalizadas asociadas con la visualización de la vista. Por ejemplo, puede usar este método para cambiar la orientación o el estilo de la barra de estado para que se coordine con la orientación o el estilo de la vista que se presenta. Si anula este método, debe llamar a super en algún momento de su implementación.

Una vez más, no puedes hacer eso desde una categoría.

Lo que quiere lograr derrota el propósito de una categoría. Sin embargo, hay otra manera aparte de subclassar UIViewController, pero debe tocar el método viewWillAppear para cada controller.

 //UIViewController+CustomCategory.h @interface UIViewConctroller (CustomCategory) - (void)performCustomization; @end //UIViewController+CustomCategory.m @implementation UIViewController (CustomCategory) - (void)performCustomization { // Do custom stuffs... } @end 

Luego en cada controller

 //MYViewController.m #import "UIViewController+CustomCategory.h" - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self performCustomization]; } 

Como estás diciendo, el código se ejecutará solo en el modo de debugging. Entonces, ¿por qué te preocupas por las advertencias para que venga la advertencia? Continúa tu trabajo cuando se trata de la liberación, eliminas tu categoría.

Si ni siquiera necesita ver la advertencia, vaya con su misma respuesta como

 #pragma clang diagnostic push #pragma clang diagnostic ignonetworking "-Wobjc-protocol-method-implementation" -(void)viewWillAppear:(BOOL)animated { NSLog(@"I get callback here too"); } #pragma clang diagnostic pop 

Pero yo diría que vaya a subclasss porque eliminar la class existente tampoco es tan difícil en la herramienta XCode.