Ios 在prepareForSegue完成之前调用viewDidLoad

Ios 在prepareForSegue完成之前调用viewDidLoad,ios,storyboard,segue,viewdidload,Ios,Storyboard,Segue,Viewdidload,我的印象是,在prepareForSegue完成后将调用viewDidLoad。这甚至是Hegarty教授斯坦福课程的方式(最近在2013年2月) 然而,今天我第一次注意到在prepareForSegue完成之前调用了viewDidLoad。因此,我在prepareForSegue中设置的属性对于DestinationViewDidLoad方法中的destinationViewController不可用 这似乎与预期的行为相反 更新 我刚弄明白发生了什么事。在我的destinationViewC

我的印象是,在prepareForSegue完成后将调用viewDidLoad。这甚至是Hegarty教授斯坦福课程的方式(最近在2013年2月)

然而,今天我第一次注意到在prepareForSegue完成之前调用了viewDidLoad。因此,我在prepareForSegue中设置的属性对于DestinationViewDidLoad方法中的destinationViewController不可用

这似乎与预期的行为相反

更新

我刚弄明白发生了什么事。在我的destinationViewController中,我有一个自定义setter,每次更新“模型”时都会重新加载tableView:

DestinationViewController    
- (void)setManagedObjectsArray:(NSArray *)managedObjectsArray
    {
        _managedObjectsArray = [managedObjectsArray copy];
        [self.tableView reloadData];
    }
事实证明,由于destinationViewController是UITableViewController的子类…调用“self.tableView”会强制加载视图。根据苹果的文档,调用视图控制器的view属性可以强制加载视图。UITableViewController的视图是tableView

因此,在prepareForSegue中,以下行强制加载destinationViewController的视图:

vc.managedObjectsArray = <custom method that returns an array>;
这将仅在tableView在屏幕上时重新加载tableView。因此,在prepareForSegue期间不会强制加载视图


如果有人反对这个过程,请分享你的想法。否则,我希望这能防止某人长时间失眠。

谢谢分享,帮我解决了问题

在我的例子中,destinationViewController是一个UITabBarController,修改它的ViewController数组会触发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 = ...
}

我过去也遇到过类似的困惑。我学到的一般经验法则是:

  • 在目标VC的viewDidLoad之前调用prepareForSegue
  • viewDidLoad仅在加载所有出口后调用
  • 不要试图在源VC的prepareForSegue中引用任何目标VC的出口
    关于prepareForSegue的另一个经验教训是避免冗余处理。例如,如果您已经通过故事板将tableView单元格分割为VC,那么如果您尝试同时处理tableView:DidSelectRowatineDexpath和prepareForSegue,则可能会遇到类似的竞争条件。可以通过使用手动序列或放弃DidSelectRowatineXpath上的任何处理来避免这种情况

    简单的解决方法是

    [self.tableView reloadData];
    

    视图中将出现

    我想对这里发生的事情添加一点解释:

    在显示视图之前调用
    prepareforsgue

    viewDidload
    在第一次访问视图时被调用(视图是延迟加载的)

    可能发生的情况是,您访问了
    prepareForSegue
    中的
    视图,手动触发视图加载。

    通常流量为:

  • preformSegue
  • prepareForSegue
  • ViewController
    已添加到层次结构中
  • viewDidLoad
  • 但你的情况可能是:

  • preformSegue
  • prepareForSegue
  • |-在
    prepareForSegue
    中,您可以访问
    视图
  • |-
    view
    自动加载=>
    viewDidLoad
    被调用
  • performsgue返回
  • ViewController被添加到层次结构中,没有
    viewDidLoad
    (已调用)

  • 因此,是的,通常在将
    ViewController
    添加到层次结构之前,不会访问
    view
    属性,但如果是,则可以提前触发
    viewDidLoad

    我的动态单元格也有类似的问题,当选中时,它会显示一个模式
    prepareForSegue
    是在
    didSelect:atIndexPath
    之前执行的。帮助我的是,在故事板中,我重新分配了从控制器开始的序列,而不是从动态单元原型开始。我解决了比赛条件(?),一切都很完美

    在我的例子中,在prepareSegue中设置destination presentationController的委托导致调用viewDidLoad。 我搬家了 segue.destination.presentationController?.delegate=self 在准备检查结束时:

        override func prepare(for segue: UIStoryboardSegue, sender: Any?)     {
        // do stuff ....
        segue.destination.presentationController?.delegate = self
         }
    

    你怎么知道调用了viewDidLoad?你能分享一些代码吗?我怀疑
    prepareForSegue
    实际上是(直接或间接)调用
    viewDidLoad
    的函数。事实上,如果你访问
    initWithCoder:
    中的outlet,它会在调用
    prepareForSegue:
    之前隐式调用
    viewDidLoad
    方法。感谢@Hampde123的评论,这有助于我了解如果我们遵循这些规则,如何在视图控制器之间传递数据?这是有意义的,但是如果不是从prepareForSegue传递参数,那么如何将参数传递到新视图?您仍然可以这样做,但需要在访问视图之前设置参数
        override func prepare(for segue: UIStoryboardSegue, sender: Any?)     {
        // do stuff ....
        segue.destination.presentationController?.delegate = self
         }