Protocol协议分发器

客官°小女子只卖身不卖艺 2023-06-02 11:53 119阅读 0赞
  1. 用途: 能够制定多个对象实现, 同一个代理方法,可以在多个对象中同时实现

2.原理: 利用消息转发机制,将方法分发到多个对象中

使用方式:

  1. self.tableView.delegate = AOProtocolDispatcher(UITableViewDelegate, self, self.delegateSource);

.h

  1. #import <Foundation/Foundation.h>
  2. #define AOProtocolDispatcher(__protocol__, ...) \
  3. [ProtocolDispatcher dispatcherProtocol:@protocol(__protocol__) \
  4. toImplemertors:[NSArray arrayWithObjects:__VA_ARGS__, nil]]
  5. @interface ProtocolDispatcher : NSObject
  6. + (id)dispatcherProtocol:(Protocol *)protocol toImplemertors:(NSArray *)implemertors;
  7. @end

.m

  1. #import "ProtocolDispatcher.h"
  2. #import <objc/runtime.h>
  3. struct objc_method_description MethodDescriptionForSELInProtocol(Protocol *protocol, SEL sel) {
  4. struct objc_method_description description = protocol_getMethodDescription(protocol, sel, YES, YES);
  5. if (description.types) {
  6. return description;
  7. }
  8. description = protocol_getMethodDescription(protocol, sel, NO, YES);
  9. if (description.types) {
  10. return description;
  11. }
  12. return (struct objc_method_description){NULL, NULL};
  13. }
  14. BOOL ProtocolContainSel(Protocol *protocol, SEL sel) {
  15. return MethodDescriptionForSELInProtocol(protocol, sel).types ? YES: NO;
  16. }
  17. @interface ImplemertorContext : NSObject
  18. @property (nonatomic, weak) id implemertor;
  19. @end
  20. @implementation ImplemertorContext
  21. @end
  22. @interface ProtocolDispatcher ()
  23. @property (nonatomic, strong) Protocol *prococol;
  24. @property (nonatomic, strong) NSArray *implemertors;
  25. @end
  26. @implementation ProtocolDispatcher
  27. + (id)dispatcherProtocol:(Protocol *)protocol toImplemertors:(NSArray *)implemertors {
  28. return [[ProtocolDispatcher alloc] initWithProtocol:protocol toImplemertors:implemertors];
  29. }
  30. - (instancetype)initWithProtocol:(Protocol *)protocol toImplemertors:(NSArray *)implemertors {
  31. if (self = [super init]) {
  32. self.prococol = protocol;
  33. NSMutableArray *implemertorContexts = [NSMutableArray arrayWithCapacity:implemertors.count];
  34. [implemertors enumerateObjectsUsingBlock:^(id implemertor, NSUInteger idx, BOOL * _Nonnull stop) {
  35. ImplemertorContext *implemertorContext = [ImplemertorContext new];
  36. implemertorContext.implemertor = implemertor;
  37. [implemertorContexts addObject:implemertorContext];
  38. objc_setAssociatedObject(implemertor, _cmd, self, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  39. }];
  40. self.implemertors = implemertorContexts;
  41. }
  42. return self;
  43. }
  44. - (BOOL)respondsToSelector:(SEL)aSelector {
  45. if (!ProtocolContainSel(self.prococol, aSelector)) {
  46. return [super respondsToSelector:aSelector];
  47. }
  48. for (ImplemertorContext *implemertorContext in self.implemertors) {
  49. if ([implemertorContext.implemertor respondsToSelector:aSelector]) {
  50. return YES;
  51. }
  52. }
  53. return NO;
  54. }
  55. - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
  56. if (!ProtocolContainSel(self.prococol, aSelector)) {
  57. return [super methodSignatureForSelector:aSelector];
  58. }
  59. struct objc_method_description methodDescription = MethodDescriptionForSELInProtocol(self.prococol, aSelector);
  60. return [NSMethodSignature signatureWithObjCTypes:methodDescription.types];
  61. }
  62. - (void)forwardInvocation:(NSInvocation *)anInvocation {
  63. SEL aSelector = anInvocation.selector;
  64. if (!ProtocolContainSel(self.prococol, aSelector)) {
  65. [super forwardInvocation:anInvocation];
  66. return;
  67. }
  68. for (ImplemertorContext *implemertorContext in self.implemertors) {
  69. if ([implemertorContext.implemertor respondsToSelector:aSelector]) {
  70. [anInvocation invokeWithTarget:implemertorContext.implemertor];
  71. }
  72. }
  73. }
  74. @end

转载于:https://www.cnblogs.com/daxueshan/p/11245748.html

发表评论

表情:
评论列表 (有 0 条评论,119人围观)

还没有评论,来说两句吧...

相关阅读

    相关 object-c的protocol(协议

    在object-c中,协议的声明类似于类接口的声明,但是,协议没有父类,而且不能定义成员变量,只能定义成员函数,而且成员函数并不是在这个协议中实现,而是要在使用它的类中实现。

    相关 Netty序列化协议Protocol buff

    序列化协议 序列化和反序列化 把对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为对象的过程称为对象的反序列化。用途:文件的copy、网络数据的传输 Pro