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(协议)来 ...
随机推荐
- Ajax局部刷新(使用JS操作)
对于在不使用Ajax的情况下,使用JS来进行局部刷新,主要有如下的几步: 1. 得到XMLHttpRequest 2. 使用open方法打开连接 3. 设置请求头信息 4. 注册onreadystat ...
- CVE-2013-2094 porting to x86-32 分析
/* * linux 2.6.37-3.8.8 - x86 * @rikiji * * requires System.map and /dev/ptmx * this: http://zmbs.ne ...
- 微信、qq网页二次分享
二次分享是指,在APP或者浏览器分享到微信或者qq,然后从微信或者qq再分享到别的平台.如果不处理,再次分享出去的图片或者标题就不会显示,对用户非常不友好. 一.微信二次分享 官方接入文档:https ...
- 对VS2019进行32位汇编环境配置
1.库文件(很重要) 用我这一份就行:https://www.lanzous.com/i6364hg 2.VS依赖库 打开VS2019,选择桌面向导 配置项目时,选择新项目. 选择生成依赖项 选中ma ...
- git_clone资源获取失败解决
github上克隆一个仓库到本地,一直失败.还以为是git安装问题,卸载重装无效:又换了个大容量的磁盘目录位置:最后ECS系统也重装还是无效.. remote: Counting objects: 5 ...
- k3 cloud中列表字段汇总类型中设置了汇总以后没有显示出汇总值
处理方法,需要bos中的分组列信息中设置求和: 选择对应字段将其从左侧添加到右侧 方法二: 直接针对[价税合计]字段的列表汇总类型进行设置,步骤如下图所示
- JavaScript面向对象编程(2)-- 类的定义
最近这一段时间事情太多了,没有时间再继续写,幸好这两天有点小闲,先小写一下JavaScript中面向对象一中推荐的方法.本文承接上一篇JavaScript面向对象编程(1) -- 基础. 上篇说过,J ...
- 阿里云LNMP环境安装
文档里有一键部署LNMP环境和手动搭建LNMP环境您看下 镜像部署 LNMP 环境:https://help.aliyun.com/document_detail/25427.html?spm=517 ...
- ERROR- 开发常见error
一,数据插入MySql中出现中文乱码 解决办法有: 1.新建数据库选择 create database 'GG' CHARACTER SET 'utf8 ' COLLATE 'utf8_general ...
- linux shell 管道命令(pipe)使用及与shell重定向区别
管道命令操作符是:”|”,它仅能处理经由前面一个指令传出的正确输出信息,也就是 standard output 的信息,对于 stdandarderror 信息没有直接处理能力.然后,传递给下一个命令 ...