iOS中通常的delegate模式只能有一个被委托的对象,这样当需要有多个被委托的对象时,实现起来就略为麻烦,在开源库XMPPFramework中提供了一个GCDMulticastDelegate类,使用它可以为一个对象添加多个被委托的对象,用起来也比较方便
一. 定义一个协议
#import <Foundation/Foundation.h>
@protocol MulticastDelegateBaseObjectDelegate <NSObject>
- (void)testDelegate;
@end
二. 创建多播对象
multicastDelegate = (GCDMulticastDelegate <MulticastDelegateBaseObjectDelegate>*)[[GCDMulticastDelegate alloc] init];
三. 创建一个类实现协议里的方法
#import "CustomLabel.h"
@implementation CustomLabel
#pragma mark - <MulticastDelegateBaseObjectDelegate>
- (void)testDelegate {
NSLog(@"-----多播");
}
@end
五. 添加代理到多播中
[multicastDelegate addDelegate:lable delegateQueue:dispatch_get_main_queue()];
四. 创建一个方法调用协议方法
- (void)test1 {
NSLog(@"test1----");
[multicastDelegate testDelegate];
// [multicastDelegate testDelegate];
}
五. 调用test1
[userInfo test1];
核心
MulticastDelegateBaseObject.h
#import <Foundation/Foundation.h>
#import "GCDMulticastDelegate.h"
#import "MulticastDelegateBaseObjectDelegate.h"//协议
//多播委托的基类
@interface MulticastDelegateBaseObject : NSObject{
id multicastDelegate;
dispatch_queue_t moduleQueue;
void *moduleQueueTag;
}
- (id)init;
- (id)initWithDispatchQueue:(dispatch_queue_t)queue;
@property (readonly) dispatch_queue_t moduleQueue;
@property (readonly) void *moduleQueueTag;
- (void)addDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
- (void)removeDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
- (void)removeDelegate:(id)delegate;
//调用test1,会使注册了的对象都执行 testDelegate 方法
- (void)test1;
@end
MulticastDelegateBaseObject.m
#import "MulticastDelegateBaseObject.h"
@implementation MulticastDelegateBaseObject
- (id)init
{
return [self initWithDispatchQueue:NULL];
}
- (id)initWithDispatchQueue:(dispatch_queue_t)queue
{
if ((self = [super init]))
{
if (queue)
{
moduleQueue = queue;
}
else
{
const char *moduleQueueName = [NSStringFromClass([self class]) UTF8String];
moduleQueue = dispatch_queue_create(moduleQueueName, NULL);
}
moduleQueueTag = &moduleQueueTag;
dispatch_queue_set_specific(moduleQueue, moduleQueueTag, moduleQueueTag, NULL);
//协议
multicastDelegate = (GCDMulticastDelegate <MulticastDelegateBaseObjectDelegate>*)[[GCDMulticastDelegate alloc] init];
}
return self;
}
//------------------
- (void)test1 {
NSLog(@"test1----");
[multicastDelegate testDelegate];
// [multicastDelegate testDelegate];
}
//------------------
- (dispatch_queue_t)moduleQueue
{
return moduleQueue;
}
- (void *)moduleQueueTag
{
return moduleQueueTag;
}
- (void)addDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue
{
dispatch_block_t block = ^{
[multicastDelegate addDelegate:delegate delegateQueue:delegateQueue];
};
if (dispatch_get_specific(moduleQueueTag))
block();
else
dispatch_async(moduleQueue, block);
}
- (void)removeDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue synchronously:(BOOL)synchronously
{
dispatch_block_t block = ^{
[multicastDelegate removeDelegate:delegate delegateQueue:delegateQueue];
};
if (dispatch_get_specific(moduleQueueTag))
block();
else if (synchronously)
dispatch_sync(moduleQueue, block);
else
dispatch_async(moduleQueue, block);
}
- (void)removeDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue
{
[self removeDelegate:delegate delegateQueue:delegateQueue synchronously:YES];
}
- (void)removeDelegate:(id)delegate
{
[self removeDelegate:delegate delegateQueue:NULL synchronously:YES];
}
@end
MulticastDelegateBaseObjectDelegate.h
#import <Foundation/Foundation.h>
@protocol MulticastDelegateBaseObjectDelegate <NSObject>
- (void)testDelegate;
@end