2012-01-30 13 views
20

Chcesz dowiedzieć się więcej o praktycznych różnicach między init a initWithNibName. Odpowiedzi SO, takie jak this sugerują, że lepiej jest wywołać "initWithNibName" pośrednio przez "init".UIViewController (init i initWithNibName)

  1. Czy istnieją jakieś okoliczności, które musimy określić „init” i „initWithNibName” inaczej?
  2. Czy możliwe jest, aby plik Nib był ładowany więcej niż raz podczas wykonywania pojedynczego programu?
  3. Czy są pytania 1 & 2 powiązane?

Odpowiedz

30

Nie lepiej zadzwonić initWithNibName: pośrednio poprzez init . Chcesz tylko zadzwonić pod numer initWithNibName: w pewnym momencie. Możesz to zrobić zewnętrznie lub wewnętrznie. Niektórzy uważają, że lepiej jest robić to wewnętrznie. W rzeczywistości mam klasę o nazwie "LayoutUtil", w której stosuję metody pomocnicze związane z układem, aby uniknąć pisania żmudnego fragmentu kodu związanego z układem w kółko. Oto mój kod załadować UIViewController:

+ (id)loadController:(Class)classType { 
    NSString *className = NSStringFromClass(classType); 
    UIViewController *controller = [[classType alloc] initWithNibName:className bundle:nil]; 
    return controller; 
} 

A potem mogę po prostu zrobić:

MyViewController *c = [LayoutUtil loadController:[MyViewController class]]; 

Jeśli chcesz, możesz dodać metodę zwaną ughhhh do klasy i nazywają go tam, to w ogóle nie ma znaczenia. Chodzi o to, że nie jest lepszą praktyką wywoływanie initWithNibName w metodzie init, ale po prostu chcesz się upewnić, że wywołasz ją w pewnym momencie podczas inicjowania kontrolera UIViewController.

- (id)ughhhh 
{ 
    self = [super initWithNibName:@"Myview" bundle:nil]; 
    if (self != nil) 
    { 
    } 
    return self; 
} 

Plik stalówka na pewno może trzeba załadować więcej niż jeden raz. Za każdym razem, gdy wywołujesz initWithNibName na kontrolerze UIViewController, należy wczytać xib. Wiele osób załadować UIViews, które nie są własnością UIViewController tak:

[[NSBundle mainBundle] loadNibNamed:@"nameOfXIBFile" owner:self options:nil]; 

każdym razem wywołać tę funkcję zostanie załadowany stalówkę.

Istnieją pewne przypadki, w których stalówka może być buforowana. Przykładem może być UITableView - ale widok tabeli implementuje własną pamięć podręczną. System operacyjny nie wykonuje automatycznie buforowania.

init i initWithNibName: są powiązane tym, że initWithNibName: automatycznie wywołuje init na obiekcie.

+1

+1, bardzo dobrze szczegółowe ... – doNotCheckMyBlog

+0

dziękuję za szczegółową odpowiedź i pomoc w naturze ... – Stanley

+1

Tylko uwaga: aby przypisać do siebie, trzeba mieć metodę zaczynającą się od 'init'. Więc '- (id) initUghhhh' – benaneesh

2

Odpowiedź pierwsze pytanie

Idealnie co initWithNibName rozmowy init wewnętrznie, dzięki czemu nie trzeba definiować zarówno w normalnym scenariuszu, ale można jeśli widok jest również ładowane od loadView w jednym przypadku i granic stalówka jako dobrze w innym przypadku z różnych widoków.

Odpowiedź Drugie pytanie

Everytime View jest popychany w Stos stalówka jest ładowany

Odpowiedź trzecim pytaniu

Nie

+0

Dzięki za odpowiedź i pomoc w naturze ... – Stanley

10

Nie "lepiej wywoływać" initWithNibName "pośrednio przez" init ". Powinieneś użyć tego, który lepiej odpowiada Twoim potrzebom. Mówienie [[UIViewController alloc] init] jest dokładnie takie, jak powiedzenie [[UIViewController alloc] initWithNibName:nil bundle:nil], więc jeśli są to argumenty, które chcesz przekazać, równie dobrze możesz użyć [[UIViewController alloc] init].

W odpowiedzi na pytania:

  1. Można zdefiniować init i initWithNibName:bundle: inaczej, jeśli chcesz. Możesz zdefiniować tylko jedną z nich. Na przykład UIImagePickerController definiuje tylko init, a próba wysłania go initWithNibName:bundle: nie będzie działać poprawnie. Lub możesz zdefiniować zupełnie inną metodę init.... Na przykład UINavigationController definiuje tylko initWithRootViewController:. Niezależnie od tego, jakie metody init zdefiniujesz, musisz w końcu wywołać jedną z metod inicjowania superklasy.

  2. Tak, stalówka może być ładowana wiele razy. Jeśli utworzysz wiele instancji tej samej podklasy kontrolerów widoków, prawdopodobnie będziesz ładować tę samą końcówkę wiele razy. W rzeczywistości możliwe jest wystąpienie pojedynczej instancji w celu wielokrotnego ładowania jej końcówki. W jaki sposób? Jeśli widok kontrolera widoku nie jest aktualnie wyświetlany na ekranie, a systemowi brakuje pamięci, system poprosi kontroler widoku o zwolnienie widoku. Jeśli kontroler podglądu musi później ponownie wyświetlić widok na ekranie, ponownie załaduje stalówkę.

  3. Pytania 1 i 2 nie są powiązane.

+0

Dzięki za szczegółową odpowiedź i życzliwą pomoc ... – Stanley

Powiązane problemy