2010-02-08 14 views

Respuesta

131

-initWithNibName:bundle: es el inicializador designado para UIViewController. Algo eventualmente debería llamarlo. Dicho esto, ya pesar de los ejemplos de Apple (que favorecen la brevedad sobre la capacidad de mantenimiento en muchos casos), nunca debería llamarse desde fuera del controlador de visualización.

Es frecuente encontrar que código como este:

MYViewController *vc = [[MYViewController alloc] initWithNibName:@"Myview" bundle:nil]; 

me dicen que esto es incorrecto. Pone los detalles de implementación (el nombre del NIB y el hecho de que incluso se usa un NIB) en la persona que llama. Eso rompe la encapsulación. La forma correcta de hacerlo es:

MYViewController *vc = [[MYViewController alloc] init]; 

Luego, en MYViewController:

- (instancetype)init 
{ 
    self = [super initWithNibName:@"Myview" bundle:nil]; 
    if (self != nil) 
    { 
     // Further initialization if needed 
    } 
    return self; 
} 

- (instancetype)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle 
{ 
    NSAssert(NO, @"Initialize with -init"); 
    return nil; 
} 

Esto mueve los detalles fundamentales de la aplicación de nuevo en el objeto, y evita que los abonados romper accidentalmente encapsulación. Ahora bien, si cambia el nombre del NIB o pasa a la construcción programática, lo arregla en un lugar (en el controlador de vista) en lugar de en cada lugar en que se usa el controlador de vista.

+3

Si esta es la manera prevista, ¿por qué generar una XCode4 initWithNibName: paquete: stub para cada clase ViewController vacío, pero ningún método init? –

+1

La misma razón por la que las plantillas no han incluido los prefijos de clase, aunque se supone que debes prefijar las clases, y la plantilla crea el nombre más tonto posible para el delegado de tu aplicación, lo cual es un verdadero dolor de cabeza para solucionar. Y IB fuerza una declaración ivar cuando crea propiedades automáticamente, aunque no debe declarar ivars en el nuevo ABI. Las plantillas no son siempre las mejores prácticas. A menudo son el denominador menos común que funciona un poco en la mayoría de los casos, pero en ningún lugar particularmente bien. El código de ejemplo de Apple está mejorando recientemente, pero todavía tiene mucho camino por recorrer. –

+1

Si sigue la convención de nombrar sus plumillas igual que la clase, entonces este código funciona bien: '- (id) init { return [super initWithNibName: NSStringFromClass ([self class]) bundle: nil]; } ' – CharlesA

6

Use initWithNibName si está ... inicializando con un archivo de punta. Es decir, un archivo que creó utilizando Interface Builder.

Si no está utilizando IB para diseñar sus vistas, puede simplemente usar init.

0

usando init cuando no hay un archivo nib/xib, p. La interfaz de usuario se crean mediante la codificación

usando initWithNibName, si tenemos un plumín/xib o misma participación controladora en más de 1 semilla/xib

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; 
} else { 
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; 
} 

que es lo que pienso ..

+0

Si agrega ~ iphone o ~ ipad a sus nombres de plumilla, puede llamar a initWithNibName @ "ViewController" y seleccionará el correcto. – Darxval

2

que sólo puede call init, siempre que el xib tenga el mismo nombre que la clase del controlador de vista. La encapsulación no es necesaria. Esto ahorra escribir, pero puede no servir claridad.

NUDMainViewController *mainVC = [[NUDMainViewController alloc] init]; 
Cuestiones relacionadas