MulticastDelegate

1 篇文章 0 订阅
1 篇文章 0 订阅

介绍:

在iOS中,两个常用的callback(回调)机制:

I delegate

II notification

delegate简单直接。用户注册自己为一个delegate,并实现它需要的delegate方法

[worker setDelegate:self];

- (void)workerDidFinish:(Worker *)sender
{
}

- (void)worker:(Worker *)sender didFinishSubTask:(id)subtask inDuration:(NSTimeInterval)elapsed
{
}

- (BOOL)worker:(Worker *)sender shouldPerformSubTask:(id)subtask
{
}
notification也很简单,但是需要多一些的准备,用户必须注册,每一个它感兴趣的notification

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(workerDidFinish:)
                                             name:WorkerDidFinishNotification
                                           object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(workerDidFinishSubTask:)
                                             name:WorkerDidFinishSubTaskNotification
                                           object:nil];

- (void)workerDidFinish:(NSNotification *)notification
{
    Worker *sender = [notification object];
}

- (void)workerDidFinishSubTask:(NSNotification *)notification
{
    Worker *sender = [notification object];
    id subtask = [[notification userInfo] objectForKey:@"subtask"];
    NSTimeInterval elapsed = [[[notification userInfo] objectForKey"duration"] doubleValue];
}

从上面可以看出,我们必须从notification object中抽出参数。有时候,我们必须从字典类型的对象里抽取参数,前提是必须知道字典中的键值。

并且,第3个delegate方法是没法通过notification实现的,因为notification机制是不允许返回变量的。


每种机制都有优点和缺点。

Delegate的优点:

    多个callback要更容易注册

    多个参数,明显要容易使用的多

    允许返回变量

Delegate的缺点:

    只能有一个delegate

notification的优点:

    多个object可以注册一个notification

notification的缺点:

    注册多个callback很繁琐

    特别烦,要抽取多个参数从字典对象中

    当需要返回变量时候,无法实现


XMPPFramework需要什么???

1. xmpp framework必须能够对多个监听者广播事件

    就比如一个简单的message,聊天窗口,历史记录,pop-up的通知都可能在监听

2. xmpp framework必须很易扩展

    它应该能够支持大量的XEP‘s,同样还要能够支持协议开发人员的自定义实现。换句话说,在广播和监听都必须很简单

3. 系统必须支持变量返回

     比如IQ(Info/Query,信息与查询)在处理mandate,如果一个用户收到了’get‘或者'set'类的消息,却不知道怎么处理,这是就一定需要返回'error',在多插件情况下,必须能够很好的执行

4. 保证线程安全

    xmpp framework是大量的并行,套接字IO,xml解析,xmpp stanza routing,模型,硬盘的IO,还有delegate全都在他们自己的GCD队列上,在多核设备上意味着多任务在不同线程同时进行,系统不能让我们through hoops保证并发和稳定。

GCDMulticastDelegate应运而生!


它长什么样???

很简单,作为用户,只需要如下操作:

// Add myself as a delegate, and tell xmppStream to invoke my delegate methods on the main thread
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];

// Then just implement whatever delegate methods you need like normal
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
   ...
}
这就是所有,就跟传统的delegate模式一样,只是可以延伸到具体是哪个线程。


如果之后,你想把你的processing从main thread中移除,也很简单:

// Handle most stuff on the main thread
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];

// But do that one slow thing on a background queue so it doesn't slow down the UI anymore
[xmppStream addDelegate:bgProcessor delegateQueue:bgProcessorQueue];

对于像iPhone这样的环境,是个非常好的方法,并不是为了创造新的paradigm而写的


我怎么使用自己的插件:

作为一个广播者,使用multicast delegate,应该如下声明和初始化:

GCDMulticastDelegate <MyPluginDelegate> *multicastDelegate;
multicastDelegate = (GCDMulticastDelegate <MyPluginDelegate> *)[[GCDMulticastDelegate alloc] init];
添加允许别人添加和删除他们到delegate list的方法:

- (void)addDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue
{
    [multicastDelegate addDelegate:delegate delegateQueue:delegateQueue];
}

- (void)removeDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue
{
    [multicastDelegate removeDelegate:delegate delegateQueue:delegateQueue];
}

如果你想对所有注册的delegates调用方法,可以:

[multicastDelegate worker:self didFinishSubTask:subtask inDuration:elapsed];
很简单,multicast delegate通知了所有的delegates,每个都在他们自己的dispatch_queue上,通过dispatch_async();


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值