iPhone SDK: qual è la differenza tra loadView e viewDidLoad?

Quando lavori con le viste e guarda i controller in un’app per iPhone, qualcuno può spiegare la differenza tra loadView e viewDidLoad?

Il mio contesto personale, è che costruisco tutte le mie viste dal codice, non lo uso e non userò Interface Builder, dovrebbe fare la differenza.

Ho scoperto che spesso quando aggiungo il codice di init a loadView, ottengo una traccia di stack infinita, quindi di solito faccio tutto il mio sviluppo di vista figlio in viewDidLoad … ma non è chiaro per me quando ognuno viene eseguito, e qual è il posto più appropriato per inserire il codice di init. Ciò che sarebbe perfetto, è un semplice diagramma delle chiamate di inizializzazione.

Grazie!

Posso indovinare quale potrebbe essere il problema qui, perché l’ho fatto:

Ho trovato che spesso quando aggiungo il codice di init a loadView, finisco con una traccia di stack infinita

Non leggere self.view in -loadView. Impostalo solo, non capirlo .

L’autore della funzione self.view chiama -loadView se la vista non è attualmente caricata. C’è la tua infinita ricorsione.

Il solito modo di build la vista a livello di codice in -loadView, come dimostrato negli esempi pre-Interface-Builder di Apple, è più simile a questo:

UIView *view = [[UIView alloc] init...]; ... [view addSubview:whatever]; [view addSubview:whatever2]; ... self.view = view; [view release]; 

E non ti biasimo per non aver usato IB. Sono rimasto fedele a questo metodo per tutti i prodotti di Instapaper e mi sono trovato molto più a mio agio rispetto alla complessità di IB, alle peculiarità dell’interfaccia e al comportamento inaspettato dietro le quinte.

loadView è il metodo in UIViewController che caricherà effettivamente la vista e la assegnerà alla proprietà view . Questa è anche la posizione in cui una sottoclass di UIViewController sovrascriverà se si desidera impostare in modo programmatico la proprietà della view .

viewDidLoad è il metodo che viene chiamato dopo aver caricato la vista. Questo viene chiamato dopo che loadView viene chiamato. È un luogo in cui è ansible eseguire l’override e inserire il codice che esegue l’ulteriore configurazione iniziale della vista dopo che è stata caricata.

 viewDidLoad() 

deve essere utilizzato quando si carica la vista da una NIB e si desidera eseguire qualsiasi personalizzazione dopo il lancio

 LoadView() 

deve essere usato quando vuoi creare la tua vista a livello di codice (senza l’uso di Interface Builder)

Aggiungendo solo alcuni esempi di codice per dimostrare cosa ha detto NilObject:

 - (void)loadView { // create and configure the table view myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStyleGrouped]; myTableView.delegate = self; myTableView.dataSource = self; myTableView.scrollEnabled = NO; self.view = myTableView; self.view.autoresizesSubviews = YES; } - (void)viewDidLoad { self.title = @"Create group"; // Right menu bar button is to Save UIBarButtonItem *saveButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStyleDone target:self action:@selector(save)]; self.navigationItem.rightBarButtonItem = saveButtonItem; [saveButtonItem release]; } 

Per evitare che un loop infinito si verifichi quando leggi self.view, chiama la super implementazione della class quando carichi una vista. La super implementazione assegnerà un nuovo UIView per te.

 - (void) loadView { [super loadview]; // init code here... [self.view addSubView:mySubview1]; //etc.. } 

Il modo più semplice per usare loadView è creare un tipo di controller di visualizzazione di base, come MyBaseViewController, che è una sottoclass di UIViewController. Nel suo metodo loadView crea la vista in questo modo:

 -(void) loadView { if ([self viewFromNib]) { self.view = [self viewFromNib]; } else { self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; } self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight; self.view.backgroundColor = [UIColor whiteColor]; } 

E quando hai bisogno di creare un controller di visualizzazione, basta usare la sottoclass di MyBaseViewController e nel suo controller loadView devi solo chiamare [super loadView] come questo

 //sucblass loadView -(void) loadView { [super loadView]; //rest of code like this.. UILabel *myLabel = [[UILabel alloc] initWithFrame:myFrame]; [self.view addSubview:myLabel]; [myLabel release]; } 

loadView() viene chiamato quando viene richiesto al controllore di creare il proprio self.view . Puoi farlo da solo come

 self.view = [UIView alloc] init...]; 

Oppure la class UIController principale del controllore ha già un metodo name -loadView() che inizializza self.view in una vista vuota. Quindi puoi chiamare

 [super loadView]; 

Consiglio vivamente il secondo approccio in quanto incoraggia l’ereditarietà. Solo se il tuo controller di visualizzazione non è direttamente ereditato da UIViewController.