Protocol协议分发器
1. 用途: 能够制定多个对象实现<Protocol>, 同一个代理方法,可以在多个对象中同时实现
2.原理: 利用消息转发机制,将方法分发到多个对象中
使用方式:
self.tableView.delegate = AOProtocolDispatcher(UITableViewDelegate, self, self.delegateSource);
.h
#import <Foundation/Foundation.h> #define AOProtocolDispatcher(__protocol__, ...) \
[ProtocolDispatcher dispatcherProtocol:@protocol(__protocol__) \
toImplemertors:[NSArray arrayWithObjects:__VA_ARGS__, nil]] @interface ProtocolDispatcher : NSObject + (id)dispatcherProtocol:(Protocol *)protocol toImplemertors:(NSArray *)implemertors; @end
.m
#import "ProtocolDispatcher.h"
#import <objc/runtime.h> struct objc_method_description MethodDescriptionForSELInProtocol(Protocol *protocol, SEL sel) {
struct objc_method_description description = protocol_getMethodDescription(protocol, sel, YES, YES);
if (description.types) {
return description;
}
description = protocol_getMethodDescription(protocol, sel, NO, YES);
if (description.types) {
return description;
}
return (struct objc_method_description){NULL, NULL};
} BOOL ProtocolContainSel(Protocol *protocol, SEL sel) {
return MethodDescriptionForSELInProtocol(protocol, sel).types ? YES: NO;
} @interface ImplemertorContext : NSObject @property (nonatomic, weak) id implemertor; @end @implementation ImplemertorContext @end @interface ProtocolDispatcher () @property (nonatomic, strong) Protocol *prococol;
@property (nonatomic, strong) NSArray *implemertors; @end @implementation ProtocolDispatcher + (id)dispatcherProtocol:(Protocol *)protocol toImplemertors:(NSArray *)implemertors {
return [[ProtocolDispatcher alloc] initWithProtocol:protocol toImplemertors:implemertors];
} - (instancetype)initWithProtocol:(Protocol *)protocol toImplemertors:(NSArray *)implemertors {
if (self = [super init]) {
self.prococol = protocol;
NSMutableArray *implemertorContexts = [NSMutableArray arrayWithCapacity:implemertors.count];
[implemertors enumerateObjectsUsingBlock:^(id implemertor, NSUInteger idx, BOOL * _Nonnull stop) {
ImplemertorContext *implemertorContext = [ImplemertorContext new];
implemertorContext.implemertor = implemertor;
[implemertorContexts addObject:implemertorContext];
objc_setAssociatedObject(implemertor, _cmd, self, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}];
self.implemertors = implemertorContexts;
}
return self;
} - (BOOL)respondsToSelector:(SEL)aSelector {
if (!ProtocolContainSel(self.prococol, aSelector)) {
return [super respondsToSelector:aSelector];
} for (ImplemertorContext *implemertorContext in self.implemertors) {
if ([implemertorContext.implemertor respondsToSelector:aSelector]) {
return YES;
}
}
return NO;
} - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
if (!ProtocolContainSel(self.prococol, aSelector)) {
return [super methodSignatureForSelector:aSelector];
} struct objc_method_description methodDescription = MethodDescriptionForSELInProtocol(self.prococol, aSelector);
return [NSMethodSignature signatureWithObjCTypes:methodDescription.types];
} - (void)forwardInvocation:(NSInvocation *)anInvocation {
SEL aSelector = anInvocation.selector;
if (!ProtocolContainSel(self.prococol, aSelector)) {
[super forwardInvocation:anInvocation];
return;
} for (ImplemertorContext *implemertorContext in self.implemertors) {
if ([implemertorContext.implemertor respondsToSelector:aSelector]) {
[anInvocation invokeWithTarget:implemertorContext.implemertor];
}
}
} @end
Protocol协议分发器的更多相关文章
- iOS 协议分发
Github:AOMultiproxier.HJProtocolDispatcher 协议实现分发器,能够轻易实现将协议事件分发给多个实现者. 一.AOMultiproxier.h #define A ...
- 开源负载均衡通讯分发器(LB dispatcher) - G5
from:http://bbs.csdn.net/topics/390753043 1.开发背景今天和系统运维的老大聊天,谈到一直在用的F5,行里对其评价为价格过高.功能复杂难懂,反正印象不是很好,使 ...
- 实现 Redis 协议解析器
本文是 <用 Golang 实现一个 Redis>系列文章第二篇,本文将分别介绍Redis 通信协议 以及 协议解析器 的实现,若您对协议有所了解可以直接阅读协议解析器部分. Redis ...
- SIP (Session Initiation Protocol) 协议
Session Initiation Protocol 介绍 SIP是VoIP技术最常使用的协议,它是一种应用程序层协议,可与其他应用程序层协议配合使用,以控制Internet上的多媒体通信会话. V ...
- jQuery源码分析系列(33) : AJAX中的前置过滤器和请求分发器
jQuery1.5以后,AJAX模块提供了三个新的方法用于管理.扩展AJAX请求,分别是: 1.前置过滤器 jQuery. ajaxPrefilter 2.请求分发器 jQuery. ajaxTran ...
- SpringMVC核心分发器DispatcherServlet分析[附带源码分析]
目录 前言 DispatcherServlet初始化过程 DispatcherServlet处理请求过程 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不 ...
- Objective-C( protocol协议)
protocol 协议 protocol:用来声明方法 1.协议的定义 @protocol 协议名称 <NSObject> // 方法声明列表.... @end 2.如何遵守协议 1> ...
- ISO 基础之 (十三) protocol 协议
一 简绍 protocol,简单来说就是一系列不属于任何类的方法列表,其中声明的方法可以被任何类实现.这种模式一般称为代理(delegation)模式.通过Protocol定义各种行为,在不同的场景采 ...
- 【转】iOS开发-Protocol协议及委托代理(Delegate)传值
原文网址:http://www.cnblogs.com/GarveyCalvin/p/4210828.html 前言:因为Object-C是不支持多继承的,所以很多时候都是用Protocol(协议)来 ...
随机推荐
- Reading query string values in JavaScript
时间 2016-01-23 13:01:14 CrocoDillon’s Blog 原文 http://crocodillon.com/blog/reading-query-string-valu ...
- Django Rest Framewoek
1 什么是RESTful REST 指的是一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.满足这些约束条件和原则的应用程序或设计就是 RESTful. 2 RESTful设计 ...
- yum安装时出现No more mirrors to try.
可能原因:可能是不正常删除造成的 解决方法: yum clean allyum makecacheyum -y update 然后重新安装
- Day5---Python的random库
random库 1.random库是随机数的Python标准库 2.原理 : random生成的伪随机数,而采用梅森旋转算法生成的(伪)随机序列中的元素叫做伪随机数 https://liam.pa ...
- Python : Data Encapsulation
Python : Data Encapsulation The following table shows the different behaviour: Name Notation Behavio ...
- hdu1394 Minimum Inversion Number (线段树求逆序数&&思维)
题目传送门 Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- P3515 [POI2011]Lightning Conductor(决策单调性分治)
P3515 [POI2011]Lightning Conductor 式子可转化为:$p>=a_j-a_i+sqrt(i-j) (j<i)$ $j>i$的情况,把上式翻转即可得到 下 ...
- 天启android5.1系统无法在非1650批次号的rk3288w芯片上启动
天启android5.1系统无法在非1650批次号的rk3288w芯片上启动 挂掉log,说明在rtc初始化后挂掉 [ ) HIGH! ======== [ [ [ 1.420258] [WLAN_R ...
- C Primer Plus 学习 第四章
字符串与格式化输入/输出 函数 strlen() 关键字 const 利用#define 和 const创建符号常量 #include <stdio.h> #include <str ...
- overload和override的含义和区别
重载(overload)和重写/覆盖(override)是Java多态性的不同表现形式. 重载(overload) (1) 重载是通过不同的方法参数来区分的,如不同的参数个数.顺序.类型. (2) 不 ...