实现一个优雅的iOS事件总线

本文探讨了iOS中Notification的痛点,如Name管理、弱类型和胶水代码,并提出了事件总线的概念,以解决这些问题。事件总线设计强调接口友好、自动取消监听和高效。文章详细介绍了如何定义事件、实现接口、取消监听以及使用宏定义优化编译期的强类型支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目标

订阅登录事件LoginEvent,当self dealloc时候自动取消订阅

[QTSub(self, LoginEvent) next:^(LoginEvent *event) {

}];

订阅通知NSNotification,当self dealloc的时候自动取消订阅

//订阅通知name
[QTSubNoti(self,"name") next:^(NSNotification *event) {

}];
//订阅App将要关闭
[[self subscribeAppWillTerminate] next:^(NSNotification *event) {

}];

并且XCode可以自动推断类型

这里写图片描述

好了,开始啰里八嗦讲原理和设计了,做好准备,文章挺长的。不想看我啰嗦,代码在这里

Notification的痛点

Cocoa Touch提供了一种消息中心机制:NSNotificationCenter,相信iOS开发者都很熟悉了,

  • addObserver 订阅通知
  • postNotification 发送通知
  • removeObserver 取消订阅

当然,还有一个接口是比较容易忽略的,就是利用block注册订阅

NSNotificationCenter * center = [NSNotificationCenter defaultCenter];
id<NSObject> token = [center addObserverForName:@"name"
                                         object:nil
                                          queue:nil
                                     usingBlock:^(NSNotification * _Nonnull note) {

                                    }];
[center removeObserver:token]

实际开发中,Notification又有哪些痛点呢?

Name如何管理?

方式一:hardcode在代码里

[center addObserverForName:@"UserLoginNotification" ...]

优点:无需额外的import,松耦合。
缺点:修改和版本管理麻烦

方式二:在相关模块的源文件里,比如登录成功的通知放在登录模块里。

//.h文件
extern NSString * const UserLoginNotification; //登录成功
//.m文件
NSString * const UserLoginNotification = @"UserLoginNotification";

优点:便于修改和版本管理
缺点:需要import引入对应的模块,导致强耦合模块,但是得到的却是弱类型。

有些同学喜欢把name堆到一个头文件里,这种设计理念是不符合软件设计原则的:“接口隔离原则,不应该强制客户端依赖那些他们不需要的接口”。想想也有道理:我不需要的通知为啥让我引入进来对吧?。

弱类型

常见的用Notification传递消息的方式是UserInfo,然后声明各种key

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值