iOS中通常的delegate模式只能有一個被委托的對象恃锉,這樣當需要有多個被委托的對象時,實現(xiàn)起來就略為麻煩螃成,在開源庫XMPPFramework中提供了一個GCDMulticastDelegate類旦签,使用它可以為一個對象添加多個被委托的對象,用起來也比較方便
一. 定義一個協(xié)議
#import <Foundation/Foundation.h>
@protocol MulticastDelegateBaseObjectDelegate <NSObject>
- (void)testDelegate;
@end
二. 創(chuàng)建多播對象
multicastDelegate = (GCDMulticastDelegate <MulticastDelegateBaseObjectDelegate>*)[[GCDMulticastDelegate alloc] init];
三. 創(chuàng)建一個類實現(xiàn)協(xié)議里的方法
#import "CustomLabel.h"
@implementation CustomLabel
#pragma mark - <MulticastDelegateBaseObjectDelegate>
- (void)testDelegate {
NSLog(@"-----多播");
}
@end
五. 添加代理到多播中
[multicastDelegate addDelegate:lable delegateQueue:dispatch_get_main_queue()];
四. 創(chuàng)建一個方法調(diào)用協(xié)議方法
- (void)test1 {
NSLog(@"test1----");
[multicastDelegate testDelegate];
// [multicastDelegate testDelegate];
}
五. 調(diào)用test1
[userInfo test1];
核心
MulticastDelegateBaseObject.h
#import <Foundation/Foundation.h>
#import "GCDMulticastDelegate.h"
#import "MulticastDelegateBaseObjectDelegate.h"http://協(xié)議
//多播委托的基類
@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;
//調(diào)用test1,會使注冊了的對象都執(zhí)行 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);
//協(xié)議
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