在prepareForSegue完成之前调用的viewDidLoad

Mic*_*ren 28 storyboard viewdidload ios segue

我认为viewDidLoad会在prepareForSegue结束后被调用.这就是Hegarty如何教他的斯坦福大学课程(最近在2013年2月).

但是,今天我第一次注意到,在READForSegue完成之前调用了viewDidLoad.因此,我在prepareForSegue中设置的属性不可用于目标viewDidLoad方法中的destinationViewController.

这似乎与预期的行为相反.

UPDATE

我只知道发生了什么事.在我的destinationViewController中,我有一个自定义setter,每次更新"model"时都会重新加载tableView:

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

事实证明,因为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>;
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我将destinationViewController模型的自定义setter更改为:

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

如果tableView在屏幕上,这将只重新加载tableView.因此,在prepareForSegue期间不强制加载视图.

如果有人反对这个过程,请分享您的想法.否则,我希望这可以防止一个人长时间不眠之夜.

Ham*_*123 25

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

  1. prepareForSegue在目标VC的viewDidLoad之前调用
  2. 只有在加载所有出口后才会调用viewDidLoad
  3. 不要尝试在源VC的prepareForSegue中引用任何目标VC的出口.

关于prepareForSegue的另一个经验教训是避免冗余处理.例如,如果您已经通过故事板将tableView单元格转换为VC,则在尝试处理BOTH tableView:didSelectRowAtIndexPath和prepareForSegue时,可能会遇到类似的竞争条件.可以通过使用手动segue或在didSelectRowAtIndexPath处放弃任何处理来避免这种情况.


Gha*_*har 2

感谢分享,帮助我解决了我的问题。

就我而言,destinationViewController 是一个 UITabBarController,修改它的 viewControllers 数组会触发 viewDidLoad:

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

在 viewDidLoad 中,我需要设置某些属性,因此我必须将其向上移动:

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