【问题标题】:Multiple Delegates in Objective CObjective C 中的多个委托
【发布时间】:2009-09-05 02:08:34
【问题描述】:

我来自 C# 事件模型,我想知道是否有一种标准方法可以通知多个代表一个事件?

我有一个 ClassCDelegate 协议,我希望 ClassA 和 ClassB 都实现。有没有一种方法可以将 ClassA 和 ClassB 的 ClassC 实例分配为委托,而无需在 ClassC 中手动创建委托变量列表并遍历它们?

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    Cocoa 委托用于完成控制反转并减少对子类化的需求。一个对象完全可以有多个委托,但是当将不同类型的决策委托给不同的对象有意义时才会这样做。一个很好的例子是来自 WebKit 的 WebView,它有五个代表负责资源加载和导航策略等不同领域。

    C# 的事件委托系统允许一个对象注册到另一个对象以在特定事件发生时得到通知,它与 Cocoa 提供的几个通知 API 最接近。您可能遇到的各种 API,从最高级别到最低级别:

    • NSNotificationCenter
    • NSDistributedNotificationCenter
    • CFNotificationCenter
    • 达尔文通知。

    在本质上都是相似的,所以我只考虑在这种情况下你会使用的那个: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];
    

    然后通知中心将查看观察者列表,找到与该通知匹配的观察者,并调用适当的方法。

    【讨论】:

    • 通知的优秀介绍及其与代表的异同。
    • 同意,这是对代表和通知(侦听器)的出色消歧。这有点模糊(例如,我们经常通知委托有关异步任务的完成),但了解其中的区别是值得的。
    【解决方案2】:

    通知中心的替代方案是使用 NSProxy 子类来转发消息,详细信息请参见:

    http://engineering.hoteltonight.com/handling-multiple-delegates-in-ios

    HTDelegateProxy 类位于:

    https://github.com/hoteltonight/HTDelegateProxy

    【讨论】:

      【解决方案3】:

      您也可以让一个对象处理该事件,然后将其转发给第二个对象。

      【讨论】:

        【解决方案4】:

        还需要注意的是,通知是单向的——它们不能像代表那样发回信息。您想要遍历委托列表的唯一情况是您的委托类希望从其委托中返回信息。

        【讨论】:

          【解决方案5】:

          您只能拥有一个委托对象。如果您想通知各种对象的更改,您应该使用 NSNotificationCenter 并发布您的对象可以侦听的 NSNotification 消息。

          【讨论】:

          • 其实这是约定俗成的,并不是严格的限制。每个人都倾向于只考虑setDelegate: 方法,但有无限的灵活性。
          【解决方案6】:

          试试MultiDelegate,它可以让你将委托方法转发给任意数量的委托对象。

          【讨论】:

            猜你喜欢
            • 2010-09-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-12
            • 1970-01-01
            • 2023-03-05
            • 2014-11-16
            相关资源
            最近更新 更多