美文网首页
2020-01-01 tangrambus事件总线学习笔记

2020-01-01 tangrambus事件总线学习笔记

作者: 我是小胡胡分胡 | 来源:发表于2020-01-01 16:46 被阅读0次

    tangrambus

    常常听同事们说的事件总线,今天研究记录一下

    一、结构-2个字典

    1,
    topic 字典, “主题”
    a,b,c,d,e,f

    参数topic

    2,
    class字典, “某一个分类,物以类聚,属于同类的”
    a1,a2,a3,a4,a5

    参数topic + identifier

    二、添加和读取

    添加:

    注意不是同时两个字典都添加, 带不带iden, 都会添加到其中一个字典里面!

    topic->添加到topic字典, 即a,b,c,d,e
    topic+iden-》添加到class字典, 即a1, a2, b1, b2, a3, a4

    读取:
    注意,是在两个字典里面都查一遍, 带不带iden,都会分别在两个字典里面查询一遍!
    topic查询
    topic+iden查询

    topic-> topic字典, 即a,b,c,d,e
    topic+iden-》 class字典, 即a1, a2, b1, b2, a3, a4
    a=> top字典找到a,执行。 class字典只有a1,a2 key,没有a,所以不执行
    a1=>top字典,取a 找到a,执行。 在class字典,有a1 key,所以执行

    关于注册

    - (void)registerAction:(NSString *)action
                ofExecuter:(id)executer
              onEventTopic:(NSString *)topic
    {
        [self registerAction:action ofExecuter:executer onEventTopic:topic fromPosterIdentifier:nil];
    }
    
    - (void)registerAction:(NSString *)anAction
                ofExecuter:(id)executer
              onEventTopic:(NSString *)topic
      fromPosterIdentifier:(NSString *)identifier
    

    关于读取

    - (void)dispatchEvent:(TangramEvent *)event
    {
        NSMutableArray *actionList = [[NSMutableArray alloc] init];
    
        NSArray *topicActions = [self.topicIndex actionsOnEvent:event];
    
    
        if (topicActions && topicActions.count > 0) {
            [actionList addObjectsFromArray:topicActions];
        }
        
        NSArray *classActions = [self.classIndex actionsOnEvent:event];
        if (classActions && classActions.count > 0) {
            [actionList addObjectsFromArray:classActions];
        }
    
        for (TangramAction *action in actionList) {
            if (action && [action isKindOfClass:[TangramAction class]]) {
                [action executeWithContext:event.context];
            }
        }
    }
    
    topic字典
    
    - (NSArray *)actionsOnEvent:(TangramEvent *)event
    {
        return [self.index tm_arrayForKey:event.topic];
    }
    
    class字典
    - (NSArray *)actionsOnEvent:(TangramEvent *)event
    {
        NSArray *actions = nil;
        if (event.identifier) {
            NSString *key = [event.topic stringByAppendingFormat:@"_%@", event.identifier];
            actions = [self.index tm_arrayForKey:key];
        }
        return actions;
    }
    

    三、例子

    调用

        TangramEvent *event = [[TangramEvent alloc] initWithTopic:@"jumpAction" withTangramView:self.inTangramView posterIdentifier:@"QRCodeClick" andPoster:self];
        [event setParam:self.rightJumpAction forKey:@"jumpAction"];
        [self.tangramBus postEvent:event];
    
     
        TangramEvent *event = [[TangramEvent alloc] initWithTopic:@"jumpAction" withTangramView:self.inTangramView posterIdentifier:@"OrderCard" andPoster:self];
        [event setParam:self.jumpAction forKey:@"jumpAction"];
        [self.tangramBus postEvent:event];
    
    ##注册
        
        [self.tangramBus registerAction:@"jumpActionHandler:"
                             ofExecuter:self
                           onEventTopic:@"jumpAction"];
    

    看看下面运行结果, 会执行3遍方法

        bus = [[TangramBus alloc] init];
        [bus registerAction:@"aMethod" ofExecuter:self onEventTopic:@"a"];
        [bus registerAction:@"aMethod" ofExecuter:self onEventTopic:@"a" fromPosterIdentifier:@"123"];
        return YES;
    }
    
    -(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        TangramEvent*event1=[[TangramEvent alloc] initWithTopic:@"a" withTangramView:nil posterIdentifier:@"123" andPoster:self];
        [bus postEvent:event1];
        
        TangramEvent*event2=[[TangramEvent alloc] initWithTopic:@"a" withTangramView:nil posterIdentifier:nil andPoster:self];
        [bus postEvent:event2];
    }
    -(void)aMethod{
        NSLog(@"aaaaa");
    }
    

    打印验证确实与分析一致:
    2020-01-01 16:43:21.189880+0800 TangramDemo[3158:1115795] aaaaa
    2020-01-01 16:43:21.190447+0800 TangramDemo[3158:1115795] aaaaa
    2020-01-01 16:43:21.191254+0800 TangramDemo[3158:1115795] aaaaa

    添加了2个字典,
    topic字典: a
    class字典:a123

    a,123命中 a 和 a123
    a命中a

    所以有3次调用

    1、注册一个topic,支持带任何标示的、或者不带标示的event
    2、注册一个topic+iden,只可以支持带标示的event
    3、一个带标示的event,可能被不带标示的处理,也可被带标示处理
    4、一个不带标示的event,只能被不带标示的处理

    这里的iden和notificationcenter的obj参数是一样的

    topic对标notificationcenter的name
    iden对标notificationcenter的object


    image.png
     给所有订阅者发送
    - (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject;
    anObject,不为空,只收到object的消息
    - (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject;
    
    

    不同在于:消息中心app系统全局单利只有一个;bus可以多个。

    四、设计思想

    有一件事情, 我不直接去做这件事, 而是将这件事存放在一个机构, 我只负责一个一个往里边存, 存一次,我通知机构一次

    机构得到我的通知, 从仓库里面把这件事重新取出来一个, 然后去执行这个事件, 一个一个“取-》做”, 直到把所有事件全部取出来完, 做完.

    就这件事来说, 我直接去做不行吗, 还要先存起来,再取出来,再做,事情还是那件事情, 经过容器转一到手, 有什么好处呢?

    - (void)postEvent:(TangramEvent *)event
    {
        [self.queue pushEvent:event];###注意这个event
        [self dispatchEvent];
    }
    
    - (void)pushEvent:(TangramEvent *)event
    {
        if ([event isKindOfClass:[TangramEvent class]]) {
            [self.queue addObject:event];####就是这个event
        }
    }
    
    - (void)dispatchEvent
    {
        __weak typeof(self) wself = self;
        dispatch_async(dispatch_get_main_queue(), ^{
            __strong typeof(wself) sself = wself;
            TangramEvent *event = [sself.queue popEvent];####还是这个event
            while (event) {
                [sself.dispatcher dispatchEvent:event];
                event = [sself.queue popEvent];
            }
        });
    }
    

    从代码可以看出来,如果push操作是在子线程,那么就不会阻塞当前线程了,这么做便于并发.

    这里和notifcationcenter的还有一个区别就是,
    notficationcenter的发送消息,消息回调是同步执行的。 跟这里tangrmbus不一样

    相关文章

      网友评论

          本文标题:2020-01-01 tangrambus事件总线学习笔记

          本文链接:https://www.haomeiwen.com/subject/kncgoctx.html