想要?Objective-C 版本的 LiveEventBus 效果(跨頁面/跨模塊通信,支持粘性和非粘性事件)。在 iOS 里對應的就是?NSNotificationCenter
,但是它?默認不支持粘性事件,所以如果你想要“粘性”,需要自己封裝一層。
1. 系統自帶方式(非粘性事件)
這是最常見的寫法(類似 Android 普通的 EventBus / LiveEventBus 的非粘性模式):
注冊監聽
// 在需要監聽的類里(比如 viewDidLoad)
[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(onUserLogin:)name:@"UserLoginNotification"object:nil];- (void)onUserLogin:(NSNotification *)notification {NSString *user = notification.userInfo[@"user"];NSLog(@"用戶登錄成功: %@", user);
}
發送通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"UserLoginNotification"object:niluserInfo:@{@"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:selfselector:@selector(onUserLogin:)sticky:YES];- (void)onUserLogin:(NSNotification *)notification {NSLog(@"粘性事件 - 登錄用戶: %@", notification.userInfo[@"user"]);
}
總結:
如果只要普通通知 → 用?
NSNotificationCenter
。如果要 LiveEventBus 粘性效果 → 用上面封裝的?
EventBus
?單例。