viewDidLoad и awakeFromNib хронометраж - PullRequest
10 голосов
/ 10 июня 2011

Насколько я понимаю, awakeFromNib всегда будет вызываться перед viewDidLoad.

Итак, у меня есть подкласс UITableViewController, который разархивирован из файла xib.

Я определил эти два метода внутри:

- (void)awakeFromNib {
  [super awakeFromNib];
  NSLog(@"awake from nib");
}

- (void)viewDidLoad {
  [super viewDidLoad];
  NSLog(@"view did load");
}

что происходит, так это то, что «view did load» появляется перед «awake from nib» в консоли. Я пытался использовать точку останова в [super awakeFromNib] и неоднократно нажимал F7 (Step Into), и, к моему удивлению, он заходил в - (void) viewDidLoad ДО перехода ко второй строке внутри awakeFromNib.

Кто-нибудь знает, что здесь происходит? Я сделал то же самое в подклассе обычного UIViewController, и операторы журнала меняются местами, как я и ожидал ...

Ответы [ 4 ]

12 голосов
/ 10 июня 2011

Чтобы понять этот факт, я рекомендую вам посмотреть loadNibNamed:owner:options: метод NSBundle.

Когда вы запускаете контроллер представления из пера, сначала он загружает содержащиеся в нем представления, а затем устанавливает владельцев файлов свойства в соответствии с пером. Метод viewDidLoad вызывается, когда он устанавливает свойство view владельца файла для одного из загруженных представлений. И awakeFromNib вызывается, когда установлены все выходы и свойства владельцев файлов (включая свойство view). Поэтому имеет смысл, что viewDidLoad вызывается раньше, чем awakeFromNib.

Надеюсь, это поможет

6 голосов
/ 10 июня 2011

Я создаю тестовый проект с опцией Приложения на основе навигации и добавляю следующие коды в rootViewController.m.

- (void)awakeFromNib {
     NSLog(@"awakeFromNib 1");
     [super awakeFromNib];
     NSLog(@"awakeFromNib 2");
}

- (void)viewDidLoad {
     NSLog(@"viewDidLoad 1");
     [super viewDidLoad];
     NSLog(@"viewDidLoad 2");
}

Затем я получаю результаты с консоли:

awakeFromNib 1
awakeFromNib 2
viewDidLoad 1
viewDidLoad 2

-(void)viewDidLoad будет вызываться при загрузке вида контроллера.Поэтому, когда вы в первый раз используете self.view = ..., будет вызываться -(void)viewDidLoad.


Если вы написали что-то вроде следующего, то сначала будет вызван -(void)viewDidLoad.

  - (void)awakeFromNib {
       NSLog(@"awakeFromNib 1");

       // The log sequence will be funny, if `viewDidLoad` raised before [super awakeFromNib]
       // If you are curios about it, just give it a try.           
       // self.view.backgroundColor = [UIColor clearColor];

       [super awakeFromNib];

       /// viewDidLoad will be called 
       /// because self.view must be loaded first.
       self.view.backgroundColor = [UIColor clearColor];  

       NSLog(@"awakeFromNib 2");
  }

и получите следующие результаты.

awakeFromNib 1
viewDidLoad 1
viewDidLoad 2
awakeFromNib 2

Обновление

loadViewIfNeeded вызовет viewDidLoad, если будет успешно загружено представление.Иногда я буду вызывать loadViewIfNeeded , чтобы убедиться, что экземпляры @IBOutlet были инициализированы и больше не равны нулю.

5 голосов
/ 10 июня 2011

Я не думаю, что вам нужно вызывать awakeFromNib в вашем суперклассе.

Проверьте это .

Редактировать

Я только что провел быстрый тест, вот результаты:

Сценарий 1 : MainWindow.Xib имеет подкласс UIViewController TestingAwakeFromNibViewController, который имеет собственный Nib-файл TestingAwakeFromNibViewController.xib.

TestingAwakeFromNibViewController имеет выход UIButton, называемый btn3. Тестирование следующего кода:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSLog(@"Btn3 %@",btn3);

    NSLog(@"viewDidLoad");
}


-(void) awakeFromNib
{
    [super awakeFromNib];

    NSLog(@"Btn3 %@",btn3);

    NSLog(@"awakeFromNib");
}

будет печатать:

Btn3 (null)
AwakeFromNib
Btn3 <UIRoundedRectButton: 0x64088e0; frame = (114 211; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x6408890>>
ViewDidLoad

Сценарий 2: Удаление файла xib, добавление UIView в качестве сына в TestingAwakeFromNibViewController внутри MainWindow.Xib и добавление UIButton в качестве подпредставления к UIView (и подключение выхода UIbutton к соответствующему выходу TestingAwakeFromNibViewController).

Запустив приведенный выше код, вы получите:

Btn3 <UIRoundedRectButton: 0x4e31c30; frame = (114 211; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4e31be0>>
viewDidLoad
Btn3 <UIRoundedRectButton: 0x4e31c30; frame = (114 211; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4e31be0>>
awakeFromNib

Значение ViewDidLoad до AwakeFromNib.

Третий сценарий : То же, что и второй, просто без звонка [super awakeFromNib];

Btn3 <UIRoundedRectButton: 0x4e0ddf0; frame = (114 211; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4e0dda0>>
awakeFromNib

Теперь ViewDidLoad даже не вызывается.

Так что, похоже, что разные сценарии требуют разных действий, и нам нужно подготовиться в соответствии с тем, по которому мы действуем.

1 голос
/ 03 апреля 2013

Не будучи экспертом и следуя этим постам, я понимаю, что в сценарии с контроллером вкладок: в «дочернем» контроллере представления метод awakeFromNib выполняется, когда загружен контроллер вкладок (родительский), но viewDidLoad только при его Вкладка "нажата.

И, следовательно, я понимаю, что это может быть использовано для загрузки данных, только когда выбрана конкретная вкладка (нажата)

...