viewDidLoad, вызываемый перед завершением подготовкиForSegue

У меня создалось впечатление, что viewDidLoad будет называться ПОСЛЕ завершения подготовкиForSegue. Это даже то, как Гегарти преподает свой класс Стэнфорда (совсем недавно, в феврале 2013 года).

Однако в первый раз сегодня я заметил, что viewDidLoad был вызван до того, как завершилась подготовкаForSegue. Поэтому свойства, которые я устанавливал в prepareForSegue, недоступны для целевогоViewController в методе viewDidLoad для адресатов.

Это противоречит ожидаемому поведению.

ОБНОВИТЬ

Я просто понял, что происходит. В моем destinationViewController у меня был настраиваемый сеттер, который будет перезагружать tableView каждый раз, когда обновляется «модель»:

DestinationViewController - (void)setManagedObjectsArray:(NSArray *)managedObjectsArray { _managedObjectsArray = [managedObjectsArray copy]; [self.tableView reloadData]; } 

Оказывается, поскольку destinationViewController является подклассом UITableViewController … вызов self.tableView заставляет просмотр загружаться. Согласно документации Apple, вызов свойства view контроллера вида может заставить загружать представление. Представление UITableViewController – это tableView.

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html

Поэтому в prepareForSegue следующая строка заставляла просматривать загрузку destinationViewController:

 vc.managedObjectsArray = <custom method that returns an array>; 

Чтобы устранить проблему, я изменил пользовательский установщик модели destinationViewController на:

 - (void)setManagedObjectsArray:(NSArray *)managedObjectsArray { _managedObjectsArray = [managedObjectsArray copy]; if ([self isViewLoaded]) { [self.tableView reloadData]; } } 

Это приведет к перезагрузке таблицыView, если tableView находится на экране. Таким образом, не заставляя представление загружаться во время подготовкиForSegue.

Если кто-то возражает против этого процесса, поделитесь своими мыслями. В противном случае я надеюсь, что это предотвратит долгую бессонную ночь для кого-то.

    Раньше я сталкивался с подобными путаницами. Общие эмпирические правила, которые я узнал:

    1. prepareForSegue вызывается перед представлением VC viewDidLoad
    2. viewDidLoad вызывается только после загрузки всех выходов
    3. Не пытайтесь ссылаться на выходные точки назначения VC в исходной версии VC's readyForSegue.

    Еще один урок, изученный в отношении подготовки forSegue, заключается в том, чтобы избежать избыточной обработки. Например, если вы уже выделили ячейку tableView в VC через раскадровку, вы можете столкнуться с аналогичным состоянием гонки, если попытаетесь обработать BOTH tableView: didSelectRowAtIndexPath и prepareForSegue. Этого можно избежать, используя либо ручной отступ, либо отказаться от любой обработки в файле didSelectRowAtIndexPath.

    Спасибо за обмен, помогли мне разобраться в моей проблеме.

    В моем случае, destinationViewController является UITabBarController и изменяет его viewControllers Array вызывает viewDidLoad:

     - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { UITabBarController *tabBarController = segue.destinationViewController; tabBarController.viewControllers = ... tabBarController.something = something; } 

    в viewDidLoad мне нужно было установить атрибут something , поэтому мне пришлось его переместить:

     - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { UITabBarController *tabBarController = segue.destinationViewController; tabBarController.something = something; tabBarController.viewControllers = ... } 

    простым решением является размещение

     [self.tableView reloadData]; 

    in viewWillAppear :

    Подумал, я бы добавил небольшое объяснение, что произошло здесь:

    prepareForSegue вызывается до отображения представления

    viewDidload вызывается при первом обращении к виду.

    Вероятно, произошло то, что вы получили доступ к view в prepareForSegue запуская загрузку представления вручную.

    Обычно поток:

    1. preformSegue
    2. prepareForSegue
    3. ViewController добавлен в иерархию
    4. viewDidLoad .

    Но то, что, вероятно, произошло в вашем случае:

    1. preformSegue
    2. prepareForSegue
    3. | – prepareForSegue
    4. | – view автоматически загружается => вызывается viewDidLoad
    5. Возврат из performSegue
    6. ViewController добавлен в иерархию, no viewDidLoad (уже вызванный)

    Таким образом, да, обычно свойство view не ViewController до того, как ViewController добавлен в иерархию, но если это так, viewDidLoad может быть запущен раньше.

    Interesting Posts

    Срок полномочий Ios Provisioning

    NMSanagedObject's willSave не вызывается для недопустимого объекта

    Могу ли я представить новую версию приложения в iTunes Connect, не отменяя прежнюю версию «Ожидает выпуска разработчика»?

    Обмен содержимым с помощью facebook sdk 4.0 + iOS

    Выключить отображение в iPhone OS (iOS)

    Как преобразовать UIImage в NSData или CFDataRef?

    SWIFT deselectRowAtIndex очень медленно при обновлении таблицы

    RestKit и ключевое значение кодирования … как обращаться с повторяющимися элементами?

    Alamofire: Поддержка загрузки многостраничных форм с текстовыми и файловыми частями?

    Как избавиться от ошибки «Неизвестное имя типа» __declspec »в Xcode

    Клавиатура скрывает поле ввода

    NSDateFormatter неверная дата

    какая система JSON с ios SDK?

    Скрыть навигационную панель, но когда я перехожу к предыдущему виду (выскочил), он временно покажет старую кнопку. Зачем?

    UICollectionView овальная форменная пользовательская ячейка

    Давайте будем гением компьютера.