容器视图控制器与childViewControllers的通信

Ale*_*ger 0 cocoa-touch delegates uiviewcontroller ios

我有一个容器视图控制器,带有3个子UIViewController子类(添加了addChildViewController).我希望我的一个子视图控制器在从容器视图控制器上删除某些内容时执行某些操作.我无法理解这种沟通应该如何发生.如果我尝试创建一个委托,我的子视图控制器中会出错,因为我会将两个子类互相导入.

Nat*_*ate 5

听起来你在编译应用程序时遇到问题,因为彼此之间存在相互的.h文件importing,对吗?

编辑:再次阅读你的问题,我不是100%清楚哪个视图控制器需要调用另一个.如果我在我的解决方案中混合了父视图控制器和子视图控制器的角色,只需切换它们即可.以下技术允许您在任何两个视图控制器(父和子,兄弟和兄弟等)之间进行通信

有很多方法可以解决这个问题.如果你想保留一个delegate模式,你可以简单地重写标题以避免#import其中一个.h文件:

ParentViewController.h:

#import "ChildViewController.h"

@interface ParentViewController: UIViewController {
@private
   ChildViewController* childVc;
}

- (void) doSomething;
Run Code Online (Sandbox Code Playgroud)

ChildViewController.h

@class ParentViewController;   // NOT #import!

@interface ChildViewController: UIViewController {
@private
   ParentViewController* parentVc;
}
Run Code Online (Sandbox Code Playgroud)

ChildViewController.m

#import "ParentViewController.h"
Run Code Online (Sandbox Code Playgroud)

这应避免循环依赖,以防止您的应用程序编译.

现在,虽然上面的工作,我可能会选择另一种解决方案,为了清洁.用一个protocol.父进程可以实现协议,然后子进程只需要有一个实现协议的委托:

#import "MyProtocol.h"

@interface ParentViewController: UIViewController<MyProtocol> {

}

- (void) doSomething;
Run Code Online (Sandbox Code Playgroud)

在MyProtocol.h中:

@protocol MyProtocol
 - (void) doSomething;
@end
Run Code Online (Sandbox Code Playgroud)

然后在ChildViewController.h中

#import "MyProtocol.h"

@interface ChildViewController: UIViewController {
@private
   id<MyProtocol> delegate;
}

@property (nonatomic, assign) id<MyProtocol> delegate;
Run Code Online (Sandbox Code Playgroud)

在ChildViewController.m中:

   [delegate doSomething];
Run Code Online (Sandbox Code Playgroud)

或者,您可以完全避免使用委托,并在控制器之间进行通信NSNotificationCenter,这会使它们稍微分离,并避免编译器循环(双向依赖).

以下是NSNotificationCenter上的Apple文档

  • 我同意这里使用协议.孩子不应该有父母的参考.但是,这不是使用NSNotificationCenter的合适位置.您可以使用它向多个对象广播消息,而不仅仅是容器中的父对象.授权是正确的解决方案. (2认同)