其他iOS Developer

[iOS 知识总结五] 多播委托

2017-07-21  本文已影响89人  pengxuyuan

需求场景

解决方法

方法一

我们可以在回调成功之后,拿到这 3 个 Label ,然后去对他进行赋值

这个办法当然可以,现在是 3 个 Label ,还比较少,如果以后改成 7 个,8 个,或者更多?我们要写多少代码?或者变成了更复杂的控件?这是灾难性的,不太可取

方法二

利用通知。我们可以在 Label 初始化的时候加个监听,请求回调成功之后发通知,Label 接收到之后做各自的处理

通知只要有地方监听了就可以收到,虽然是简单很多,但是有时候会超出我们的预期,比如我们只想让三个 Label 进行事件处理,但是其他地方也监听了,那么,其他地方也会进行事件处理,我们不能对其进行约束。这样子,代码越写越多,可能会导致一些乱七八糟的问题

而且 iOS 的通知简直不要太麻烦,要注册,还得在适当的时候从消息中心移除,如果新加一个控件简直写到心累。。。。

方法三

能不能有这样一种实现,我们封装一个东西出来,在回调成功之后,只调用一个方法,就可以分发到我们想处理的控件中,让它们自己进行事件处理?

多播委托就是这种模式,下面我们就看一下多播委托的实现原理

如何实现多播委托

实现一对多代理主要要实现以下两点:

  1. 我们需要知道有哪些对象需要进行监听,这里我们用一个数组来保存
  2. 然后对于代理的消息需要一一转发到这个数组里面的对象中去

这里需要用到类似蹦床模式的思想:一个类不做任何事情,只是负责转发消息

转发消息我们可以利用Objective-C 中的消息转发机制来转发,代码示例如下:

//1.创建一个中间类来保存需要转发的对象们&转发消息
/*
PXYMulticastDelegate 这个类我继承自NSProxy,因为NSProxy 这类就是专门用来转发消息的,比较恰当
这里提供几个方法,增加需要监听的对象,并且可以设置回调的队列
*/

@interface PXYMulticastDelegate : NSProxy

- (instancetype)init;

- (void)addDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
- (void)removeDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
- (void)removeDelegate:(id)delegate;
- (void)removeAllDelegate;

@end
/*
PXYMulticastDelegate 具体核心方法
*/
#pragma mark - 蹦床模式 消息转发
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector  {
    for (PXYMulticastDelegateNode *node in _observers) {
        id nodeDelegate = node.delegate;
        NSMethodSignature *result = [nodeDelegate methodSignatureForSelector:aSelector];
        if (result != nil) {
            return result;
        }
    }
    
//    return [super methodSignatureForSelector:aSelector];
    return [[self class] methodSignatureForSelector:@selector(doNothing)];
}

- (void)forwardInvocation:(NSInvocation *)anInvocation {
    SEL selector = [anInvocation selector];
    
    for (PXYMulticastDelegateNode *node in _observers) {
        id nodeDelegate = node.delegate;
        dispatch_queue_t delegateQueue = node.delegateQueue;
        if ([nodeDelegate respondsToSelector:selector]) {
            dispatch_async(delegateQueue, ^{
                [anInvocation invokeWithTarget:nodeDelegate];
            });
        }
    }
}
//使用

_multicastDelegate = (PXYMulticastDelegate<ViewControllerDelegate> *)[[PXYMulticastDelegate alloc] init];
    
[_multicastDelegate addDelegate:self delegateQueue:nil];
[_multicastDelegate addDelegate:_test2 delegateQueue:nil];

self.delegate = _multicastDelegate;
[self.delegate test];

设计思想:

这里就是多播委托了,平时需要用到多播委托,如果不想自己写的话,可以使用GCDMulticastDelagate 这个帮助类

参考文献�

IOS 多播委托(GCDMulticastDelegate)

XMPPFramework

上一篇 下一篇

猜你喜欢

热点阅读