iphone objective-c cocoa-touch designated-initializer

iphone - Qué inicializador(es) anular para la subclase UITableViewController



objective-c cocoa-touch (5)

Implementar:

- (void) viewDidLoad

y hacer su inicialización de componentes allí.

Tiene la ventaja de que solo se realiza la inicialización cuando la vista se solicita realmente.

O simplemente haga un método de configuración separado invocado por todos los inicializadores.

Tengo una subclase UITableViewController que está instanciada, dependiendo de dónde se usa, en un NIB o mediante un código. En ambos casos quiero hacer la personalización en el método de inicialización. ¿ initWithNibName:bundle: significa que necesito implementar tanto initWithNibName:bundle: como initWithCoder: y cada método llamaría a su respectivo súper inicializador?

Si bien no necesito esto ahora, ¿qué initWithStyle: si también quiero poder crear una instancia del controlador de vista con initWithStyle: :? ¿Necesitaría entonces 3 métodos de inicio diferentes que repliquen el mismo comportamiento?

Parece que esto viola toda la convención de inicialización designada, ya que esencialmente habría 3 inicializadores separados que no terminan llamando un método de inicio común. ¿O hay una manera de crear un inicializador designado común mientras se admiten las 3 rutas de instanciación diferentes?


Internamente,

  • UITableViewController''s -initWithStyle: llama a los súper -init luego establece el _tableViewStyle ivar.
  • UIViewController''s -init simplemente llama a -initWithNibName:bundle: con los argumentos predeterminados.
  • UITableViewController no anula -initWithNibName:bundle:

Por lo tanto, si reemplaza -initWithNibName:bundle: then -initWithStyle: también adoptará el cambio. Por supuesto, para jugar de forma segura (ya que no debe confiar en los detalles de la implementación), anule ambos.

(Y no es necesario anular -initWithCoder: menos que -initWithCoder: -archive / archive las instancias).


Mi confusión se basó en la creencia errónea de que cada clase debería tener un solo inicializador designado. Esto no es cierto, y en el caso de UITableViewController hay 3 inicializadores designados (por lo que puedo decir):

  1. initWithStyle: declarado localmente
  2. initWithNibName:bundle: heredado de UIViewController
  3. initWithCoder: de adoptar el protocolo NSCoding

Debe anular 1 o más de estos en su subclase, dependiendo de cómo se instancia su subclase. En mi caso, tuve que implementar # 2 y # 3 ya que la clase se puede cargar desde un NIB, o se puede crear una instancia a través de un código con referencia a un NIB. (Me imagino que es raro que use tanto initWithStyle: como initWithNibName:bundle: para una sola clase).

Considero que las Pautas de Codificación de Apple para Cocoa son útiles.


Para aclarar, initWithStyle: siendo el único inicializador publicado de UITableViewController en los documentos, es su inicializador explícito designado.

initWithNibName:bundle: se hereda de UIViewController y es el inicializador designado para esa clase. Como tal, de acuerdo con las pautas de Cocoa, UITableViewController debe anular este método (implementándolo). Sin embargo, esto no lo convierte en un inicializador designado de UITableViewController .

initWithCoder: es, como usted señala, un inicializador designado implícito de NSCoding .


Una adición a las publicaciones sobre esa referencia –initWithCoder:

Si agregó el controlador de vista a su principal a través del generador de interfaz (por ejemplo: si el controlador de vista está conectado a un controlador de barra de pestañas en el generador de interfaz), debe anular –initWithCoder.

(-initWithNibName solo se llamará cuando cree el controlador de vista mediante programación).