0

我实现了一个自定义UIViewController,它有多个子视图控制器(主要是通过使用故事板Container View,但不仅仅是)。

我想知道“根”视图控制器向其子级发送消息的最佳方式是什么,考虑到发送的消息所涉及的子级视图控制器不一定是“根”视图控制器?

例如:

查看控制器层次结构

我想从#0视图控制器#1#4. 天真的实现是遍历子节点#0并向他们发送消息,如下所示:

for (UIViewController *childVC in self.childViewControllers)
{
    if ([childVC respondsToSelector:@selector(myMessage:)])
    {
        [childVC performSelector@selector(myMessage:)];
    }
}

但它根本不起作用,因为#3会收到消息(或者如果它是 aUINavigationController并且我正在调用自定义方法,则可能不会收到)并且不会将其传播给它的孩子(这里#4)。

那么是否有可能向自己的孩子发送消息,并让消息通过UIViewController层次结构传播?

如果没有,另一种方法是使用NSNotificationCenter,让对消息感兴趣的孩子(#1#4)观察通知,并在必要时让根视图控制器发布通知。但我觉得只给两个孩子发信息有点过头了。

4

4 回答 4

4

我倾向于避免NSNotificationCenter,因为如果一个人不小心它会创建一些意大利面条代码。尽管如此,在这种情况下,我还是会使用它,因为采用消息应该如何在 childsViewControllers 之间传播的逻辑以及 ochildsViewControllers 的子代的可能性更加过大。

于 2013-03-07T19:09:01.790 回答
0

我认为通过NSNotificationCenter是最好的方法。每个子视图控制器可以自己决定他们想要响应哪些通知;它负责过滤掉发布通知的对象。

于 2013-03-07T19:10:49.157 回答
0

你也可以做这样的事情,但我并不是说这是一个好主意:

@interface UIViewController (ReverseResponder)

- (void)reverseRespond:(SEL)selector withObject:(id)object;

@end

@implementation UIViewController (ReverseResponder)

- (void)reverseRespond:(SEL)selector withObject:(id)object
{
    if ([self respondsToSelector:selector]) {
        [self performSelector:selector withObject:object];
    }

    for (UIViewController* childViewController in self.childViewControllers) {
        [childViewController reverseRespond:selector withObject:object];
    }
}
于 2013-03-07T19:14:27.427 回答
0

您可以使用 self.childViewControllers 访问所有孩子,并传递特定索引以获取特定孩子。要到达 4,您必须访问 3 的 topViewController。

UIViewController *child4 = [(UINavigationController *)self.childViewControllers[2] topViewController];

这是否是执行此操作的好方法,取决于您要执行的操作。你为什么要发送消息到这个级别?

于 2013-03-07T19:32:16.630 回答