viewDidLoad called before prepareForSegue finishes

前端 未结 5 619
梦毁少年i
梦毁少年i 2020-12-24 12:46

I was under the impression that viewDidLoad will be called AFTER prepareForSegue finishes. This is even how Hegarty teaches his Stanford class (as recently as Feb 2013).

相关标签:
5条回答
  • 2020-12-24 12:57

    Thought I'd add a little explanation on what happened here:

    prepareForSegue is called before the view is displayed

    viewDidload is called the first time the view is accessed (view is lazy loaded).

    What probably happened is that you accessed the view in prepareForSegue triggering the view loading manually.

    Usually the flow is:

    1. preformSegue
    2. prepareForSegue
    3. ViewController is added to the hierarchy
    4. viewDidLoad.

    But what probably happened in your case is:

    1. preformSegue
    2. prepareForSegue
    3. |— In prepareForSegue you access the view
    4. |— view is automatically loaded => viewDidLoad is invoked
    5. Return from performSegue
    6. ViewController is added to the hierarchy, no viewDidLoad (already called)

    So yes usually the view property is not accessed before the ViewController is added to the hierarchy, but if it is, viewDidLoad can be triggered earlier.

    0 讨论(0)
  • Thanks for sharing, helped me figure my problem out.

    In my case, the destinationViewController is a UITabBarController and modifying it's viewControllers Array triggered the viewDidLoad:

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

    in the viewDidLoad I needed the something attribute to be set, so I had to move it up:

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        UITabBarController *tabBarController = segue.destinationViewController;
        tabBarController.something = something;
         tabBarController.viewControllers = ...
    }
    
    0 讨论(0)
  • 2020-12-24 13:16

    I had a similar problem with my dynamic cell which showed a modal when selected. prepareForSegue was executed before didSelect:atIndexPath. What helped me was that in the storyboard I reassigned the segue to start from the controller and not the dynamic cell prototype. I solved the race condition (?) and everything is working perfectly!

    0 讨论(0)
  • 2020-12-24 13:18

    I had run into similar confusions in the past. The general rules of thumb that I learned are:

    1. prepareForSegue is called before destination VC's viewDidLoad
    2. viewDidLoad is called only after ALL outlets are loaded
    3. Do not attempt to reference any destination VC's outlets in source VC's prepareForSegue.

    Another lesson learned with regards to prepareForSegue is to avoid redundant processing. For example, if you already segue a tableView cell to a VC via storyboard, you could run into similar race condition if you attempt to process BOTH tableView:didSelectRowAtIndexPath and prepareForSegue. One can avoid such by either utilizing manual segue or forgo any processing at didSelectRowAtIndexPath.

    0 讨论(0)
  • 2020-12-24 13:20

    the simple solution is to place

    [self.tableView reloadData];
    

    in viewWillAppear:

    0 讨论(0)
提交回复
热议问题