2010-02-08 15 views

risposta

131

-initWithNibName:bundle: è l'inizializzatore designato per UIViewController. Qualcosa dovrebbe infine chiamarlo. Detto questo, e nonostante gli esempi di Apple (che favoriscono la brevità sulla manutenibilità in molti casi), non dovrebbe mai essere chiamato al di fuori del controller stesso.

Vedrete spesso il codice come questo:

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

dico questo non è corretto. Mette i dettagli dell'implementazione (il nome della NIB e il fatto che persino un NIB è usato) nel chiamante. Questo rompe l'incapsulamento. Il modo corretto per farlo è:

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

Poi, in 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; 
} 

Questo sposta i dettagli di implementazione chiave in oggetto, e impedisce ai chiamanti di rottura accidentale incapsulamento. Ora, se si modifica il nome del NIB o si passa alla costruzione programmatica, lo si aggiusta in un punto (nel controller della vista) anziché in ogni punto in cui viene utilizzato il controller della vista.

+3

Se questo è il modo previsto, perché XCode4 genera un initWithnibName: bundle: stub per ogni classe ViewController vuoto, eppure nessun metodo init? –

+1

Lo stesso motivo per cui i modelli non hanno incluso prefissi di classe, anche se si suppone che si prefiggano prefissazioni alle classi e il modello crei il nome più stupido possibile per il delegato dell'app, che è un vero problema da risolvere. E IB impone una dichiarazione di ivar durante la creazione automatica delle proprietà, anche se non dovresti dichiarare ivars nel nuovo ABI. I modelli non sono sempre le migliori pratiche. Sono spesso il minimo comune denominatore che funziona un po 'nella maggior parte dei casi, ma da nessuna parte particolarmente bene. Il codice di esempio di Apple sta migliorando di recente, ma ha ancora una strada da percorrere. –

+1

Se si segue la convenzione di denominare i propri pennini allo stesso modo della classe, questo codice funziona bene: '- (id) init { return [super initWithNibName: NSStringFromClass ([self class]) bundle: nil]; } ' – CharlesA

6

Utilizzare initWithNibName se si sta inizializzando con un file di pennino! Cioè, un file che hai creato usando Interface Builder.

Se non si utilizza IB per impaginare le viste, è sufficiente utilizzare init.

0

utilizzando init quando non è presente il file pennino/xib, ad es. UI sono creati da codifica

utilizzando initWithnibName, se abbiamo un pennino/XI ter o stessa quota di controllo di oltre l'1 pennino/XI ter

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

questo è quello che penso ..

+0

Sapete se aggiungete ~ iphone o ~ ipad ai nomi dei pennini, potete semplicemente chiamare initWithNibName @ "ViewController" e sceglierà quello corretto. – Darxval

2

Si può solo chiama init, purché lo xib abbia lo stesso nome della classe del controller di visualizzazione. L'incapsulamento non è necessario. Ciò consente di risparmiare la digitazione, ma potrebbe non servire alla chiarezza.

NUDMainViewController *mainVC = [[NUDMainViewController alloc] init]; 
Problemi correlati