iOS : 为什么我们在添加视图时需要添加子视图控制器,因为子视图可​​以工作?

iOS : Why do we need to add child view controller when adding view as subview does the work?

有一个 ViewController1,它有一个 stackView。 我创建了一个 ViewController2 的实例,并将它的视图作为子视图添加到 ViewController1 的 stackView 中,我想看看是否只有通过这样做才会调用 ViewController2 的 viewDidLoad 并且确实如此,当我将 ViewController2 的视图添加到ViewController1 的堆栈视图。例如:在 ViewController1self.stackView.addArrangedSubView(viewControler2.view) 那么为什么我们需要执行 addChild(viewController2) 然后将视图添加为子视图,那些添加 childController 的典型行及其在父视图控制器层次结构中的视图

当然viewDidLoad被调用了。一旦您在代码中引用 ViewController2 的 view,就会立即发生这种情况。

但假设您的 ViewController2 除了加载视图之外还做其他事情。假设它的视图包含一个按钮,该按钮通过一个操作挂接到 ViewController2 中的一个函数。如果你现在点击那个按钮,什么也不会发生。

那是因为 ViewController2 本身已经死了:它已经烟消云散了。

您可以通过在 ViewController2 中实现 deinit 来看到这一点。您会看到,正如 viewDidLoad 被调用一样,deinit 也是如此。您留下了一个没有视图控制器的视图控制器视图。太糟糕了。

有一个视图控制器hierarchy负责维护视图控制器之间的关系。当您将 ViewController2 添加为 ViewController1 的 child 视图控制器时,您会维护该层次结构,并根据规则正确维护它,即:

If VC2's view is somewhere inside VC1's view, then VC2 needs to be a child (at some depth) of VC1.

换句话说,视图层级和视图控制器层级必须运行在一起。否则,响应链就会断裂,生活就会变得混乱。


(当您使一个视图控制器成为另一个视图控制器的 child 时,还有其他要求,例如将 didMoveToParent 发送到 child 作为开场舞的一部分,以及其他消息稍后转发责任,以确保 child 视图控制器在正确的时间获得其他消息,如 viewDidAppear。这是一项复杂的业务。但是,我将我的回答集中在最基本的部分你问的。)


我要补充一点:如果您的目标只是从 nib 中获取 view 并将其填充到您自己的视图中,您当然可以做到,没问题。你不能做的是使用 view controller 作为一种磁铁或真空吸尘器来为你获取视图,如果你打算放开视图控制器本身的话。