2009-09-25 10 views
8

Ten paciencia conmigo, todavía estoy aprendiendo Cocoa Touch. Otro -viewDidLoad al no ser llamado pregunta no estaba relacionado con mi problema, sí busqué.-viewDidLoad no llamado en UIViewController subclasificado

Tengo FooViewController, una subclase UIViewController. FooViewController.xib tiene su propietario de archivo configurado en FooViewController. Además, tengo Main, cuyo delegado de la aplicación es MyApplication y cuyo propietario del archivo es UIApplication. Mi plumilla principal está configurada en Principal.

soy capaz de hacer la vista aparecen en la pantalla, el uso de este flujo (código cortado con tijeras por razones de brevedad):

UIWindow *main; 

-(void)applicationDidFinishLaunching:(UIApplication*)application { 
    [self showFooViewController]; 
    [main makeKeyAndVisible]; 
} 

-(void)showFooViewController { 
    fooViewController = [[FooViewController alloc] init]; 
    if(![[NSBundle mainBundle] loadNibNamed:@"FooViewController" owner:fooViewController options:nil]) { 
     DebugF(@"Failed to load FooViewController"); 
     return; 
    } 

    // Add the view and put it in place 
    UIView *view = [fooViewController view]; 
    CGRect cur = [view frame]; 
    cur.origin = CGPointMake(0.0f, 20.0f); 
    [view setFrame:cur]; 

    [main addSubview:[fooViewController view]]; 
} 

Sin embargo, este mensaje no se envía a FooViewController:

- (void) viewDidLoad { 
    DebugF(@"Hello!"); 
} 

Silencio total en la salida de gdb.

He visto otros tutoriales de Cocoa que muestran instancias y demás en la vista de documento de IB, pero no veo estas opciones en el mío. ¿Se supone que estoy creando instancias de fooViewController en el Nib? ¿Perdí una conexión? En FooViewController.xib, la vista del propietario del archivo está conectada a la vista en el Nib.

Estoy seguro de que esta es una solución simple, y he vagado por el camino equivocado. ¡Halp!

Respuesta

18

no he encontrado la documentación que respalde lo siguiente, pero esto es lo que he deducido por el experimento/experiencia:

Se espera que el método viewDidLoad ser llamado inmediatamente después de loadView se llama, y ​​le toca a quien llama al loadView para suministrar la llamada adicional al viewDidLoad.

En algunos casos, el SDK manejará este comportamiento por usted. Supongamos que tiene una subclase de UIViewController llamada MyViewController; entonces:

  • Si accede a myViewController.view antes de llamar loadView, a continuación, el descriptor de acceso superclase es lo suficientemente inteligente como para llamar loadView para usted, y viewDidLoad inmediatamente después.

Como resultado, si el código es el siguiente:

MyViewController *myViewController = [[MyViewController alloc] init]; 
[superView addSubview:myViewController.view]; // Calls viewDidLoad. 

entonces ambos loadView y viewDidLoad se llamará en su nombre.

Sin embargo, si su código es el siguiente:

MyViewController *myViewController = [[MyViewController alloc] init]; 
[myViewController loadView]; 
[superView addSubview:myViewController.view]; // Doesn't call viewDidLoad. 

entonces el view captador puede ver que ya ha cargado la vista, y se supone que también llamado viewDidLoad también - por lo que no llama ya sea. Irónicamente, la llamada de función adicional aquí impide que se llame a viewDidLoad.

+4

De acuerdo con la documentación "Nunca debe llamar a este método [loadView] directamente". –

+0

Gracias, Peter - Veo a lo que te refieres. Aquí está el enlace, en caso de que alguien quiera leer la fuente original (de Apple): http://developer.apple.com/iphone/library/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#// apple_ref/occ/instm/UIViewController/loadView – Tyler

+0

Tuve exactamente el mismo problema (llamar directamente a 'loadView'), gracias por la información. –

3

Y respondí mi propia pregunta, por lo que esto puede ayudar a los futuros. Como veo que viewDidLoad tiene, como sugieren los tres Googles superiores, "viewDidLoad no se llama", "viewDidLoad no se llama" y "viewDidLoad no se activa", me imagino que este es un error habitual ...

Changing :

fooViewController = [[FooViewController alloc] init]; 
if(![[NSBundle mainBundle] loadNibNamed:@"FooViewController" owner:fooViewController options:nil]) { 
    DebugF(@"Failed to load FooViewController"); 
    return; 
} 

Para:

fooViewController = [[FooViewController alloc] initWithNibName:@"FooViewController" bundle:[NSBundle mainBundle]]; 

ha solucionado el problema. Obviamente es un error en la forma en que estoy usando Cocoa.

+1

Es una cosa pequeña, pero si pasa el paquete por nulo, se verá en el paquete principal. –

+0

Lamentablemente, la última llamada hace que sea imposible especificar opciones, lo que significa que no puede usar objetos proxy. Pero parece que tendré que ignorar viewDidLoad y llamar a mi propio método de forma manual. –

4

He tenido el mismo problema dos veces. La primera vez, olvidé conectar la vista de UITableViewController al UITableView actual en el constructor de interfaces. La segunda vez, olvidé hacer que awakeFromNib se llame a sí mismo en la superclase.

Cuestiones relacionadas