通过故事板创建 ViewController 与通过 alloc/init

Creation of ViewControllers by the storyboard vs. by alloc/init

我正在使用 Xcode 6.3,Objective-C。

在我的故事板中,我创建了一个 UINavigationController。然后我创建一个 UIViewController 并将其指定为 UINavigationController 的根控制器。然后我创建第二个 UIViewController,并使用 "manual show" segue 将它连接到第一个 UIViewController

所以我的故事板有一个 UINavigationController 和两个 UIViewControllers,都连接好了。我在第一个 UIViewController 中也有一个按钮,它具有显示第二个 UIViewController 的操作(稍后会详细介绍......)

我的问题是:app运行时,所有的Controller是不是一次性创建的?

潜在的问题是,当我点击按钮显示第二个 UIViewController 时,使用通常的 [self.navigationController pushViewController:controller animated:YES],第二个 UIViewController 是否已经存在 - 由于已经存在在故事板加载和解析时创建?

或者,在推送之前,我需要先做一个[... alloc] init]吗?

我知道,如果您以编程方式创建 UIViewControllers,您肯定需要执行 allocinit。但是我不清楚当 UIViewController 已经在故事板中 "created" 时是否需要 alloc/init

使用 [self performSegueWithIdentifier...] 测试连接似乎有效:显示了第二个 UIViewController,但没有完成明确的 alloc/init。所以在我看来,目标控制器是在执行 segue 时由 UIKit 创建的(alloc/init)。你不需要做那部分。

但是如果我想使用 ...pushViewController:controller... 方法显示第二个 UIViewController,我将如何获得指向它的指针? UINavigationController 中的 UIViewController 数组只有一个元素,而不是两个——这是有道理的:只有当第二个控制器被压入堆栈时,该数组才会添加第二个控制器的引用。

所以,如果我想做一个 ...pushViewController:controller...,假设第二个 UIViewController 确实存在(因为它是由情节提要创建的),我怎样才能得到指向它的指针- 在第一个控制器中?

或者,我是否必须首先使用 "alloc/init" 显式创建它,这当然会给我指针?

在我看来,如果故事板创建了所有控制器,那么对它们的引用必须存在于某处。

而且,如果是这样,在故事板已经创建的第二个控制器上执行 "alloc/init" 步骤是多余的,对吗?

或者,即使我在故事板中创建了第二个 UIViewController,我仍然需要用 "alloc/init" 消息实例化它?

当然,对第二个控制器进行手动 segue 没有意义,因为您没有利用 UINavigationController,而且它实际上是多余的。因此,要利用导航,您必须使用 ...pushViewController:controller... 方法,这需要指向第二个控制器的指针。天真地,这表明需要 "alloc/init" 。但同样,我不明白为什么你需要显式创建 class 实例,而故事板(如果我理解正确的话)会为我完成。

我知道 "alloc/init" 只会创建对象;没有设置任何属性。为此,我需要 instantiateViewControllerWithIdentifier。但是我仍然手动创建第二个控制器,对吧?所以故事板不会在运行时为我实例化它们?

我知道故事板调用 initWithCoder 然后 awakeFromNib,这表明故事板实际上在应用程序运行时实例化了这些对象。但是,当应用程序运行时,它会理所当然地这样做吗,还是我仍然需要明确地手动执行某些操作?我还在追求的是一个指向第二个控制器的指针,以便在推送中使用,where/how我可以获得这个指针。

抱歉这个问题很长:我只是想更清楚地说明我目前的理解以及我的问题是什么。是的,我是 iOS n00b - 这就是为什么我要来这里寻求专家帮助的原因。为此,我非常感谢你。

如果您在故事板中创建了 UIViewController,它们似乎是一次性初始化的。如果您使用故事板,则不需要 alloc/init。使用转场。如果你不想使用 segues 然后使用:

//这里我们以编程方式实例化了一个视图控制器

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"View controller storyboard id"];

在情节提要中设置情节提要 ID(身份检查器):)

然后就加Push一个ViewController:

[self.navigationController pushViewController:controller animated:YES];

或者如果您没有使用导航控制器:

[self presentViewController:controller animated:YES completion:nil];

My question is this: When the app runs, are all the Controllers created all at once?

不,只创建了初始控制器(故事板中带有箭头的那个)。如果它是 Navigation controller,它的根视图控制器也会被创建。

Or, before doing the push, do I need to do a [... alloc] init] first?

是的,您必须 alloc init 您的 ViewController 才能将其推送到导航堆栈中。尚未创建。

在后台,如果您使用故事板,它会调用 initWithCoder: 来初始化您的视图控制器。然后,您可以通过 prepareForSegue: 方法设置它的属性。

如果您使用编码方法,只需 alloc init 您的控制器,设置它的属性和 pushToViewController

很简单吧?

how can I get the pointer to it - in the first controller?

是的,通过 prepareForSegue: 方法,您的新控制器是 segue.destinationViewController

...

我觉得够了,我的回答几乎涵盖了你所有的问题。如果您需要进一步的解释,请随时问我。