【发布时间】:2009-09-05 02:08:34
【问题描述】:
我来自 C# 事件模型,我想知道是否有一种标准方法可以通知多个代表一个事件?
我有一个 ClassCDelegate 协议,我希望 ClassA 和 ClassB 都实现。有没有一种方法可以将 ClassA 和 ClassB 的 ClassC 实例分配为委托,而无需在 ClassC 中手动创建委托变量列表并遍历它们?
【问题讨论】:
标签: objective-c
我来自 C# 事件模型,我想知道是否有一种标准方法可以通知多个代表一个事件?
我有一个 ClassCDelegate 协议,我希望 ClassA 和 ClassB 都实现。有没有一种方法可以将 ClassA 和 ClassB 的 ClassC 实例分配为委托,而无需在 ClassC 中手动创建委托变量列表并遍历它们?
【问题讨论】:
标签: objective-c
Cocoa 委托用于完成控制反转并减少对子类化的需求。一个对象完全可以有多个委托,但是当将不同类型的决策委托给不同的对象有意义时才会这样做。一个很好的例子是来自 WebKit 的 WebView,它有五个代表负责资源加载和导航策略等不同领域。
C# 的事件委托系统允许一个对象注册到另一个对象以在特定事件发生时得到通知,它与 Cocoa 提供的几个通知 API 最接近。您可能遇到的各种 API,从最高级别到最低级别:
NSNotificationCenterNSDistributedNotificationCenterCFNotificationCenter在本质上都是相似的,所以我只考虑在这种情况下你会使用的那个:NSNotificationCenter。
ClassA 和 ClassB 等观察者通过NSNotificationCenter 注册他们对通知的兴趣。他们可以指定对
当匹配的通知发布到通知中心时,通过调用他们在通知中心注册时提供的方法来通知观察者。该方法始终具有相同的类型:它不返回任何内容并接受单个参数,即 NSNotification 对象。
您通常会通过让 ClassC 在其头文件中为通知名称声明一个常量来处理您的情况,例如,
extern NSString *const ClassCSomethingDidHappenNotification;
感兴趣的观察者,例如 ClassA 和 ClassB,可以注册对此通知的兴趣:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(handleSomethingDidHappen:)
name:ClassCSomethingDidHappenNotification
object:aClassCObject];
除了注册一个选择器并向观察者添加一个方法来处理回调,您现在还可以注册一个操作队列和一个块,以便在发布匹配的通知时在该队列上执行。
当与通知相关的事件发生时,ClassC 将通知发布到通知中心:
[[NSNotificationCenter defaultCenter]
postNotificationName:ClassCSomethingDidHappenNotification
object:self];
然后通知中心将查看观察者列表,找到与该通知匹配的观察者,并调用适当的方法。
【讨论】:
通知中心的替代方案是使用 NSProxy 子类来转发消息,详细信息请参见:
http://engineering.hoteltonight.com/handling-multiple-delegates-in-ios
HTDelegateProxy 类位于:
【讨论】:
您也可以让一个对象处理该事件,然后将其转发给第二个对象。
【讨论】:
还需要注意的是,通知是单向的——它们不能像代表那样发回信息。您想要遍历委托列表的唯一情况是您的委托类希望从其委托中返回信息。
【讨论】:
您只能拥有一个委托对象。如果您想通知各种对象的更改,您应该使用 NSNotificationCenter 并发布您的对象可以侦听的 NSNotification 消息。
【讨论】:
setDelegate: 方法,但有无限的灵活性。
试试MultiDelegate,它可以让你将委托方法转发给任意数量的委托对象。
【讨论】: