实现多代理(消息转发)

2019-11-02  本文已影响0人  寂寞先森666

需求:创建一个单例person,要求person上的更新内容在vc1、vc2实时变化

#import <Foundation/Foundation.h>
#import "MultiDelegate.h"


@protocol personDelegate <NSObject>
-(void)eating;
@end

@interface person : NSObject
+(instancetype)share;
@property(strong,nonatomic) MultiDelegate <personDelegate> * delegate;
@end
#import "person.h"
@interface person()
@property(strong,nonatomic)NSTimer * timer;
@end
@implementation person
+ (instancetype)share
{
    static person * p = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (p == nil) {
            p = [[person alloc]init];
            p.delegate = [[MultiDelegate alloc]init];
            p.timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
                [p.delegate eating];
            }];
        }
    });
    return p;
}
@end

创建MultiDelegate

#import <Foundation/Foundation.h>

@interface MultiDelegate : NSObject

- (void)addDelegate:(id)delegate;

@end
#import "MultiDelegate.h"
@interface MultiDelegate()
@property(strong,nonatomic)NSMutableArray * delegates;
@end
@implementation MultiDelegate

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.delegates = [NSMutableArray array];
    }
    return self;
}
- (void)addDelegate:(id)delegate {
    [self.delegates addObject:delegate];
}
//返回方法签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    NSMethodSignature * signature;
    for (id delegate in self.delegates) {//存储了各个对象的代理
        signature = [delegate methodSignatureForSelector:selector];
        if (signature)
        {
            break;
        }
    }
    return signature;
}
//找到真正的消息接受者
- (void)forwardInvocation:(NSInvocation *)invocation {
    SEL selector = [invocation selector];
    for (id delegate in self.delegates) {//遍历存储给个对象的代理,发送给每个要实现代理方法的对象
        if (delegate && [delegate respondsToSelector:selector]) {
            //触发方法调用
            [invocation invokeWithTarget:delegate];
        }
    }
}

@end

在vc1、vc2中使用

vc1

- (void)viewDidLoad {
    [super viewDidLoad];
    [[person share].delegate addDelegate:self];
}
-(void)eating
{
    NSLog(@"vc1 eating...");
}

vc2

- (void)viewDidLoad {
    [super viewDidLoad];
    [[person share].delegate addDelegate:self];
}
-(void)eating
{
    NSLog(@"vc2 eating...");
}

打印结果
2019-08-30 14:30:28.119098+0800 yyModel测试[23455:763215] vc1 eating...
2019-08-30 14:30:28.119306+0800 yyModel测试[23455:763215] vc2 eating...
2019-08-30 14:30:29.119138+0800 yyModel测试[23455:763215] vc1 eating...
2019-08-30 14:30:29.119496+0800 yyModel测试[23455:763215] vc2 eating...

上一篇 下一篇

猜你喜欢

热点阅读