iOS开发之一款轻量级的EventBus

IMXEventBus

#功能列表:

  • 以订阅/发布的模式实现跨组件通信,也即通信模块。类似NSNotification的通信功能。
  • 生命周期管理:注册的事件订阅者可自动释放,也可手动管理其释放时机。
  • 优先级处理:触发事件时,通过预设值的优先级,决定执行订阅者回调的先后顺序。
  • 订阅者回调在主线程/非主线程执行的控制。
  • Debug模式下:增加输出所有Event信息。

#如何使用:

1.)导入:

  1. Cocoapods:pod 'IMXEventBus', '~> 1.0.0'

  2. 手动导入:本库无依赖其它三方库,直接将IMXEventBus文件夹拖入项目即可。

    Github地址:https://github.com/PanZhow/IMXEventBus

2.)头文件引入:

#import "IMXEventBusKit.h"

3.)功能使用:

1. 注册:
  1. 简略模式:

      //默认值:
      //优先级:Default;回调执行:非主线程
      [IMXEventSubscriber addTarget:self name:@"login_eventName"     action:^(IMXEventUserInfo *info) {
        NSLog(@"callback info:%@    thread:%@",[info description],[NSThread currentThread]);
      }];
    
  2. 全参模式:

    [IMXEventSubscriber addTarget:self name:@"login_eventName" priority:IMXEventSubscriberPriorityDefault inMainTread:YES action:^(IMXEventUserInfo *info) {
        NSLog(@"callback info:%@    thread:%@",[info description],[NSThread currentThread]);
    }];
    
    
  • 默认情况下,优先级是default,回调均是在非主线程下执行。
2. 触发事件:
  1. 简略模式:

        //默认值:
        //被触发的事件:不强制在主线程中执行回调
        [IMXEventPoster postEventName:@"login_eventName"    object:@{@"userName":@"demo"}];
    
    
  2. 全参模式:

    [IMXEventPoster postEventName:@"login_eventName" object:nil forceMain:YES];
    
  • 默认情况下,firceMain:NO。即所有被触发的监听对象,其回调执行均参考自身属性isInMainThread;否则均强制在主线程执行。
3. Debug:
  1. 功能汇总(仅在Debug模式下,log处理):

    1. 重复添加target对应的同一事件时,会打印或者弹出log提示。

    2. post时,无对应的监听者存在,会打印或者弹出log提示。

      1. Debug模式下:输出所有Event信息。(便于检测当前无订阅者的僵尸事件以及未被触发的事件)

      注:仅输出之前的Event调用情况,无法检测输出之后的log,故输出的数目不代表最终数据。

  2. 开启Debug功能:默认不开启。

    
    [IMXEventDebug_share enableDebug:YES];
    IMXEventDebug_share.debugType = IMXEventDebugTypeAlert;
    
    
  • 无论如何设置,Debug功能仅在Debug模式下起作用。

#要点及图谱:

  • 注册事件、触发事件、移除事件等操作均针对同一队列操作:所有操作均嵌入异步串行队列之中,保证了资源存取的线程安全。
  • 事件监听者对象分别由3个不同优先级的NSMapTable队列存储:以Target:Model方式存储,对应Target由于生命周期问题释放后,那么事件队列中相关条目会被自动释放。但无法实时检测到,故发布事件时均需巡检一次。
  • 触发事件时:轮询3个不同优先级对类,执行每个监听者对象的回调:执行操作均放在并行队列中,并创建信号量控制线程的数量。且并行队列嵌入在串行队列中,保证3个对类按其优先级顺序执行。

图谱1:类图结构

IMXEventBus类图.png

图谱2:事件注册流程图

IMXEventBus注册监听.png

图谱3:事件触发流程图

IMXEventBus触发.png

#结构描述:

一、数据:

1. IMXEventSubscribModel:订阅者对象
  • 数据

    1. actionBlock:post触发时执行该回调
    2. priority:优先级,决定订阅者对象预置入哪个队列以及后续执行序列。(在IMXEventBus中使用)
    3. isInMainThread:是否在主线程/非主线程执行actionBlock
    4. target:弱引用形式,暂未使用场景
  • 行为:

    1. actionWIthInfo:forceMainThread::回调执行最终实现
2. IMXEventUserInfo:poster传输数据
  • 数据

    1. userInfo:字典对象
    2. 待扩展

二、逻辑处理:

1. IMXEvent:事件
  • 功能:单一事件对象。

    1. 注册订阅者对象
    2. 响应poster触发事件
    3. 即管理和调度订阅者队列
  • 数据:

    1. eventName:事件名称,唯一标识一个事件。
    2. mapHigh、mapDefault、mapLow:私有属性。订阅者队列。NSMaptable定制,target释放,对应记录也自动释放的特性。
  • 行为:

    1. hasContainedSubscribModelForKey::检查各队列中是否包含Key对应的订阅者。

    2. registSubscribModel:forKey::注册订阅者至对应队列。

    3. postEventWithDeliveryData:isInMain:事件出发,逐个执行事件中各队列的订阅者行为。

      1. 并行队列嵌入至串行队列:保证3个优先级队列顺序执行。
      2. 并行队列:保证单个事件队列中各订阅者行为并行执行。
      3. 信号量处理:控制线程数量,并行数。
    4. deleteEntryForTarget::删除事件中Target对应的一条订阅者记录。

    5. isEmptyMap:各优先级对应的队列是否全为空

2. IMXEventBus:单例模式,事件集合。
  • 数据:

    1. events:事件集合。所有针对该集合的处理均在异步线程中串行执行,非阻塞主线程行为。
  • 行为:

    1. registSubscribModel:markEvent:priority:inMainTread:action::注册订阅者
    2. publishEvent:delivery:isFromMainTread::触发事件
    3. unregistSubscribModelFromTarget:: 解注册Target对应的订阅者:若解除后事件无相关订阅者,则移除该Event对象。
    4. removeEvent:: 移除事件

三、public文件:

1. IMXEventSubscriber:注册订阅者

主要是针对IMXEventBus注册接口的封装。如将优先级是否主线程执行回调统一置常用值为默认值。

2. IMXEventPoster:post触发事件

主要是针对IMXEventBus发布接口的封装。将是否主线程执行回调统一置常用值为默认值。

#待完善:

  1. Target子类化对象中与Target本身存在有同名事件处理问题(过滤去重功能)。
  2. 延时触发事件。
  3. 条件触发。
  4. 其它

#参考:

#更新Pods开源库

  1. 提交code至github,或改version或保持不变(更改版本时不需要第3步骤)。
  2. pod trunk register email@XX.com '<name>' --description='<description>'
  3. pod trunk delete IMXEventBus 1.0.0
  4. pod trunk push --allow-warnings
  5. 使用时:pod setup更新

参考链接:https://www.jianshu.com/p/d6beddcce8bb

更多

  • 纰漏之处,欢迎斧正。
  • 更多内容请关注公众号:IT互联网自习室
IT互联网自习室.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,265评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,274评论 1 288
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,087评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,479评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,782评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,218评论 1 207
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,594评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,316评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,955评论 1 237
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,274评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,803评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,177评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,732评论 3 229
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,953评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,687评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,263评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,189评论 2 258

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,535评论 25 707
  • 对于Android开发老司机来说肯定不会陌生,它是一个基于观察者模式的事件发布/订阅框架,开发者可以通过极少的代码...
    飞扬小米阅读 1,420评论 0 50
  • 本篇前置阅读: 创业公司如何做好财务那点事? 创业者应该知道的税务知识:基础篇 我发现周围的创业者们,90%以上都...
    黄非说阅读 2,169评论 9 32
  • 我最亲爱的妈妈,我是你的小宝宝,从什么时候开始认识你的呢?我也记不清啦,好早好早,或者是上一辈子也说不定哦! 我现...
    莞小主阅读 406评论 0 0
  • 一个判断 if 条件 : input返回的是字符串!!!!! 2个条件判断 if : else: 多个条件判断 ...
    夏日春风阅读 276评论 0 0