viewDidLoad и awakeFromNib сроки

насколько я понимаю, 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, и операторы log отменены, как я изначально ожидал...

4 ответов


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

когда вы вводите контроллер вида из nib, прежде всего он загружает представления, которые там содержатся, а затем устанавливает владельцы файлом "свойства" по данным Сиб. viewDidLoad метод вызывается, когда он устанавливает view свойство одного из загруженных представлений. И awakeFromNib вызывается, когда установлены все выходы и свойства владельцев файлов (включая view свойство.) Так что имеет смысл, что viewDidLoad вызывается раньше, чем awakeFromNib.

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


Я не думаю, что вы должны позвонить 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 даже не вызывается.

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


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

- (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 = ..., the -(void)viewDidLoad будет ссылаться.

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

  - (void)awakeFromNib {
       /// viewDidLoad will be called 
       /// because self.view must be loaded first.
       self.view.backgroundColor = [UIColor clearColor];  
       [super awakeFromNib];
       NSLog(@"awakeFromNib 2");
  }

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

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