2009-09-25 2 views
8

Ayez de la patience avec moi, j'apprends toujours Cocoa Touch. Autre -viewDidLoad n'étant pas appelé question n'était pas lié à mon problème, j'ai fait une recherche.-viewDidLoad n'est pas appelé dans UIViewController sous-classé

J'ai FooViewController, une sous-classe UIViewController. FooViewController.xib a son propriétaire de fichiers défini sur FooViewController. De plus, j'ai Main, dont le délégué de l'application est MyApplication et dont le propriétaire du fichier est UIApplication. Ma plume principale est définie sur Principal.

Je suis en mesure de faire le point de vue apparaissent sur l'écran, en utilisant ce flux (code snipped par souci de concision):

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]]; 
} 

Cependant, ce message n'est pas envoyé à FooViewController:

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

Silence total dans la sortie de gdb.

J'ai vu d'autres tutoriels Cocoa qui montrent des Instances et autres dans la vue document d'IB, mais je ne vois pas ces options dans les miennes. Suis-je censé instancier fooViewController dans la Nib? Ai-je manqué une connexion? Dans FooViewController.xib, la vue Propriétaire du fichier est connectée à la vue dans la plume.

Je suis sûr que c'est une solution simple, et j'ai erré dans le mauvais chemin. Halp!

Répondre

18

Je n'ai pas trouvé la documentation pour sauvegarder ce qui suit, mais est ce que j'ai déduis par expérience/expérience:

La méthode viewDidLoad devrait être appelé immédiatement après loadView est appelé, et il est à quiconque appelle loadView pour fournir l'appel supplémentaire à viewDidLoad.

Dans certains cas, le SDK gère ce comportement pour vous. Supposons que vous avez une sous-classe de UIViewController appelée MyViewController; puis:

  • Si vous accédez à myViewController.view avant d'appeler loadView, le accesseur superclasse est assez intelligent pour appeler loadView pour vous et viewDidLoad immédiatement après.

En conséquence, si votre code ressemble à ceci:

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

alors à la fois loadView et viewDidLoad seront appelés en votre nom.

Cependant, si votre code ressemble à ceci:

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

alors le view getter peut voir que vous avez déjà chargé la vue, et il suppose que vous aussi appelé viewDidLoad aussi bien - il ne remet pas non plus. Ironiquement, l'appel de fonction supplémentaire ici empêche viewDidLoad d'être appelé.

+4

Selon la documentation "Vous ne devriez jamais appeler cette méthode [loadView] directement". –

+0

Merci, Peter - Je vois de quoi tu parles. Voici le lien, au cas où quelqu'un voudrait lire la source originale (d'Apple): http://developer.apple.com/iphone/library/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#// apple_ref/occ/instm/UIViewController/loadView – Tyler

+0

J'ai eu exactement le même problème (en appelant 'loadView' directement), merci pour l'info. –

3

Et j'ai répondu à ma propre question, donc cela peut aider les gens à venir. Comme je vois viewDidLoad a, comme mes trois premiers Googles dans mon suggèrent, "viewDidLoad pas appelé", "viewDidLoad ne pas appelé", et "viewDidLoad ne pas tirer", j'imagine que c'est une erreur habituelle ...

:

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

Pour:

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

Correction du problème. Évidemment, une erreur dans la façon dont j'utilise Cocoa.

+1

C'est une petite chose, mais si vous passez le bundle à zéro, cela apparaîtra dans le bundle principal. –

+0

Malheureusement, ce dernier appel rend impossible la spécification d'options, ce qui signifie que vous ne pouvez pas utiliser d'objets proxy. Mais il semble que je devrais simplement ignorer viewDidLoad et appeler ma propre méthode manuellement. –

4

J'ai eu le même problème deux fois. La première fois, j'ai oublié de connecter la vue de UITableViewController à l'UITableView actuelle dans le constructeur de l'interface. La deuxième fois, j'ai oublié de faire awakeFromNib se appeler dans la superclasse.

Questions connexes