Objective-C 版本的 LiveEventBus 效果

想要 Objective-C 版本的 LiveEventBus 效果 (跨页面/跨模块通信,支持粘性和非粘性事件)。在 iOS 里对应的就是 NSNotificationCenter,但是它 默认不支持粘性事件,所以如果你想要"粘性",需要自己封装一层。


1. 系统自带方式(非粘性事件)

这是最常见的写法(类似 Android 普通的 EventBus / LiveEventBus 的非粘性模式):

注册监听

复制代码
// 在需要监听的类里(比如 viewDidLoad)
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(onUserLogin:)
                                             name:@"UserLoginNotification"
                                           object:nil];

- (void)onUserLogin:(NSNotification *)notification {
    NSString *user = notification.userInfo[@"user"];
    NSLog(@"用户登录成功: %@", user);
}

发送通知

复制代码
[[NSNotificationCenter defaultCenter] postNotificationName:@"UserLoginNotification"
                                                    object:nil
                                                  userInfo:@{@"user": @"Tom"}];

特点:

  • 简单,零依赖。

  • 不支持"粘性事件",也就是说如果事件在订阅前就发了,新订阅者不会收到。


2. 封装一个带粘性事件的 EventBus

自己写一个单例,存储最后一次事件,当新订阅时立即触发一次:

复制代码
@interface EventBus : NSObject
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSNotification *> *stickyEvents;
+ (instancetype)shared;
- (void)post:(NSString *)name userInfo:(NSDictionary *)userInfo sticky:(BOOL)sticky;
- (void)observe:(NSString *)name observer:(id)observer selector:(SEL)selector sticky:(BOOL)sticky;
@end

@implementation EventBus

+ (instancetype)shared {
    static EventBus *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[EventBus alloc] init];
        instance.stickyEvents = [NSMutableDictionary dictionary];
    });
    return instance;
}

- (void)post:(NSString *)name userInfo:(NSDictionary *)userInfo sticky:(BOOL)sticky {
    NSNotification *notification = [NSNotification notificationWithName:name object:nil userInfo:userInfo];
    if (sticky) {
        self.stickyEvents[name] = notification;
    }
    [[NSNotificationCenter defaultCenter] postNotification:notification];
}

- (void)observe:(NSString *)name observer:(id)observer selector:(SEL)selector sticky:(BOOL)sticky {
    [[NSNotificationCenter defaultCenter] addObserver:observer selector:selector name:name object:nil];
    if (sticky) {
        NSNotification *last = self.stickyEvents[name];
        if (last) {
            // 手动立即分发上一次事件
            #pragma clang diagnostic push
            #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
            [observer performSelector:selector withObject:last];
            #pragma clang diagnostic pop
        }
    }
}

@end

使用示例

发布事件
复制代码
[[EventBus shared] post:@"UserLoginNotification"
               userInfo:@{@"user": @"Tom"}
                 sticky:YES];
订阅事件(新订阅者会马上收到粘性事件)
复制代码
[[EventBus shared] observe:@"UserLoginNotification"
                  observer:self
                  selector:@selector(onUserLogin:)
                    sticky:YES];

- (void)onUserLogin:(NSNotification *)notification {
    NSLog(@"粘性事件 - 登录用户: %@", notification.userInfo[@"user"]);
}

总结:

  • 如果只要普通通知 → 用 NSNotificationCenter

  • 如果要 LiveEventBus 粘性效果 → 用上面封装的 EventBus 单例。