实例化视图控制器标识符似乎会调用viewDidLoad方法。

9
我将尝试使用编程方式将一个视图控制器推入到导航控制器中,在此过程中我会使用我的故事板来创建它。
以下是我的代码:
+ (void) pushViewController:(NSString *) identifier ForItems:(NSMutableArray *) items sender:(UIViewController *) sender {
    GenericViewController *viewController = (GenericViewController *)[sender.storyboard instantiateViewControllerWithIdentifier:identifier];

    viewController.items = [[NSMutableArray alloc] init];
    [viewController.items removeAllObjects];
    [viewController.items addObject:[[NSMutableArray alloc] init]];
    [viewController.items[0] addObjectsFromArray:items];

    [sender.navigationController pushViewController:viewController animated:YES];
}

GenericViewController viewDidLoad中,我正在使用我的items。通过一些断点,我发现在instantiateViewControllerWithIdentifier之后,GenericViewController viewDidLoad会出现一个items为nil的情况。
我认为MyViewController viewDidLoad是在pushViewController 方法中调用的。
有什么想法,为什么viewDidLoadinstantiateViewControllerWithIdentifier期间被调用? ---更新: 这是我的viewDidLoad代码:
- (void)viewDidLoad
{
    for (MyItem *currentItem in self.items[0]) {
        [Do Something]
    }

    [super viewDidLoad];


    [...]
}

self.items 是空的,因此没有进行任何操作。


请放上完整的代码。myItem和viewDidLoad方法是什么?问题不在这里,因为当你初始化一个对象时,它就已经存在了。 - Matteo Gobbi
你需要提供更多的信息。请展示使用instantiateViewControllerWithIdentifier:方法的整个方法。该方法——instantiateViewControllerWithIdentifier:不会导致viewDidLoad被调用,因此可能有其他原因。 - rdelmar
谢谢@rdelmar,我很确定instantiateViewControllerWithIdentifier不会调用viewDidLoad。我更新了我的代码,现在使用静态管理器来实例化并推送我的新视图控制器。 - Thomas Besnehard
我仍然没有看到您发布的代码中会导致viewDidLoad在推送之前调用的任何内容。您是否设置了任何segue到GenericViewController? GenericViewController是一个独立的控制器(不嵌入任何内容)吗? - rdelmar
4个回答

8

对于任何可能遇到相同问题的人。

我曾经遇到类似的情况,并通过调用loadViewIfNeeded()方法解决了问题。

let sb: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let controller = sb.instantiateViewControllerWithIdentifier("LoadingView") as! LoadingViewController
controller.loadViewIfNeeded()

我可以访问视图内的所有内容。


根据文档所述,不应直接调用loadView()方法。 https://developer.apple.com/reference/uikit/uiviewcontroller/1621454-loadview - Ramiro

3

1

参见:https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewDidLoad

viewDidLoad 方法在控制器的视图被加载到内存中时被调用。

viewWillAppear 方法通知视图控制器其视图即将被添加到视图层级中。我认为这是在调用 [self.navigationController pushViewController:viewController animated:YES]; 时发生的。

viewDidAppear 方法通知视图控制器其视图已经添加到视图层级中。这是当 MyViewController 被添加到 navigationController 中时发生的。


这是有意义的,但是一些Stack Overflow的问题表明这是将属性传递给视图控制器的好方法。(https://dev59.com/tWHVa4cB1Zd3GeqPmm7L#9666389, https://dev59.com/imnWa4cB1Zd3GeqPxiZV#12709167) - Thomas Besnehard

0
正如voyage11所提到的,viewDidLoad在控制器的视图加载到内存中时被调用,尽管有人指出这并不一定发生在instantiateViewControllerWithIdentifier方法期间。
根据您的示例代码,我会将循环放在viewWillAppear方法中:
- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];  // good practice to call the super
    for (MyItem *currentItem in self.items[0]) {
        [Do Something]
    }
}

你的初始语句是不正确的 - 仅通过实例化视图控制器,viewDidLoad 不会被调用。 - rdelmar
好观点。我已经更新了我的回答,以排除那个暗示。 - Mark Semsel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接