2011-01-28 2 views
5

Problema molto interessante quando si utilizza loadView in UIViewController.Ciclo infinito quando si utilizza loadView

Di solito abbiamo usato come questo senso

// Implement loadView to create a view hierarchy programmatically, without using a nib. 
- (void)loadView { 
    NSLog(@"loadview"); 
    [super loadView]; 
} 

Se rimuovere

[super loadView]; 

Avremo ciclo morto con questa

- (void)loadView { 
    NSLog(@"loadview"); 

} 

Perché?

risposta

4

Poiché si sta semplicemente EREDITANDO cosa viene implementato in super classe (UIViewController), se non si chiamano super metodi, l'implementazione che deve essere eseguita NON viene eseguita.

Quasi tutti i metodi super fanno qualcosa di critico e la classe locale che eredita le implementazioni di super-classe deve o sovrascriverli tutti insieme (a meno che tu non sappia tutto su cosa fa super facendo riferimento alla documentazione, non è mai una buona idea), o semplicemente AGGIUNGI implementazione della classe locale alle implementazioni di super-classe ereditate.

In conclusione, ogni volta che si eredita una classe, che è nella maggior parte dei casi di sviluppo del software, è necessario consentire alla super classe di eseguire le sue implementazioni, a meno che non sia sicuro sovrascriverle.

Se sono corretto, sembra che super loadView implementa qualcosa di molto critico per evitare il loop.

NOTA COMPLEMENTARE: Tuttavia, sulla base della documentazione, è non dovrebbe chiamata super-metodo: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html Probabilmente, il motivo per il ciclo infinito è causato dalla mancata attuazione view proprietà in modo appropriato.

9

Solo un modo per creare un ciclo infinito in questo caso - sta ottenendo la proprietà di visualizzazione finché non è impostata. Se si scrive successiva (per esempio):

- (void)loadView { 
    self.view = [[UIView alloc] initWithFrame:self.view.bounds]; 
} 

Avrete ottenuto ciclo infinito, ma

- (void)loadView { 
    self.view = [[UIView alloc] initWithFrame:CGRectZero]; 
} 

funziona bene.

Quindi non è possibile accedere alla proprietà vista finché non non l'hai impostata.

2

Se si esegue il override di loadView, è necessario fornire una vista di root per la gerarchia delle viste del controllore. Se non lo si fornisce, loadView viene richiamato ogni volta che si fa riferimento alla vista, probabilmente portando a un ciclo infinito. Da documenti:

Se si specificano le viste manualmente, è necessario implementare il metodo loadView e utilizzarlo per assegnare un oggetto di visualizzazione radice alla proprietà di visualizzazione.

implementazioni che potrebbero causare un ciclo infinito:

- (void)loadView { 
    NSLog(@"loadview"); 
} 

... auto.la vista è nil dopo loadView

- (void)loadView { 
    self.view; // Or anything that references self.view 
} 

... il riferimento a self.view causa l'invocazione di loadView, quindi un ciclo infinito.

corretta:

- (void)loadView { 
    self.view = [[UIView alloc] init]; 
    if (self.view == nil) { 
     [super loadView]; // Try to load from NIB and fail properly, also avoiding inf. loop. 
    } 
} 
+1

Questa è la risposta corretta, non quello contrassegnato come accettato – Pascal