5

Encontré algo interesante, quiero saber si estoy haciendo algo mal o si este es el comportamiento correcto.Cargando XIB automáticamente para UITableViewController

Tengo un UITableViewController personalizado. Asumí (primer error) que si se inicializa como tal:

[[CustomTableController alloc] init]; 

sería cargar automáticamente desde un XI ter del mismo nombre, CustomTableController.xib, si está en el mismo directorio y tal.

Sin embargo

Esto no funciona; no carga el XIB. PERO, si cambio la clase padre de mi controlador de 'UITableViewController' a 'UIViewController', ¡TODO FUNCIONA BIEN!

Calling:

[[CustomTableController alloc] init]; 

carga el controlador y vista desde mi xib.

¿Estoy haciendo algo mal? ¿Es esto un error? ¿Comportamiento esperado?

Respuesta

26

La mayoría de las clases en Cocoa Touch enumeran un "inicializador designado" al que se supone que debe llamar desde sus métodos init cuando los subclasifica. Cuando crea su propia clase personalizada, es una buena idea consultar la documentación para encontrar el inicializador designado para su superclase. Cuando inicializa la clase utilizando algún otro inicializador de una superclase más general (lo que está haciendo al llamar al [NSObject init] en este caso), le roba a su superclase directa la oportunidad de inicializar correctamente su estado. A veces puedes salirte con la tuya. A menudo no puedes.

La documentación de UIViewController indica que su inicializador designado es - initWithNibName:bundle:. Si llama a este método con nil NibName, buscará una punta que coincida con su nombre de clase. El comportamiento de -init no está documentado para UIViewController. Según el comportamiento que está viendo, parece que puede estar llamando al [self initWithNibName:nil bundle:nil], pero sería más seguro llamar al initWithNibName:bundle: directamente en lugar de confiar en este comportamiento no documentado.

UITableViewController solo define un único inicializador, -initWithStyle: (aunque no especifica este método como el inicializador designado). Este método inicializa su UITableViewController sin usar un plumín, que generalmente está bien. Como no agrega subvistas a una UITableView, generalmente no se gana mucho configurando su UITableViewController a través de un plumín.

Si decide que quiere configurar su UITableViewController a través de una punta de todos modos, la documentación nos dice que podemos pasar por alto con seguridad -initWithStyle: y llamar al método de UIViewController initWithNibName:bundle:. Esto es lo que la documentación nos dice acerca de cómo nuestro UITableView y su controlador se inicializan en cada caso:

  • Si se especifica un archivo de semilla a través del método initWithNibName:bundle: (que es declarado por el UIViewController superclase), UITableViewController carga la vista de tabla archivada en el archivo nib. De lo contrario, crea un objeto UITableView sin configurar con las dimensiones correctas y la máscara de autoresize. Puede acceder a esta vista a través de la propiedad tableView.

  • Si se carga un archivo de punta que contiene la vista de tabla, la fuente de datos y el delegado se convierten en los objetos definidos en el archivo de punta (si corresponde). Si no se especifica ningún archivo nib o si el archivo nib no define ningún origen de datos o delegado, UITableViewController configura el origen de datos y el delegado de la vista de tabla como propio.

En resumen, la documentación para la mayoría de las clases de Cocoa Touch o bien especificar un único inicializador designado o un puñado de valores de inicialización que se pueden llamar de forma segura desde sus subclases. Siempre consulte la documentación de su superclase para averiguar a qué inicializador debe llamar su subclase.

+0

Excelente respuesta, gracias! Ojalá pudiera darte más puntos. – ACBurk

+0

Mi aplicación falla cuando creo un xib con una UIView y una UITableView e intento de cargar esa xib con initWithNibName como usted describe. Se queja "- [UITableViewController loadView] cargó la plumilla" XXXXXXTableViewController "pero no obtuvo una UITableView. ' También intenté hacer que la vista raíz del xib fuera solo una UITableView, pero cuando lo hago, la aplicación se carga pero no aparece nada de la personalización que he hecho en la aplicación./ –

+0

Pensé que me estaba volviendo loco cuando parecía que estaba cargando plumillas con el mismo nombre que la clase. Muy buena explicación. – zekel