From e87e3037b22925252579c20b06892bd33d4cc2f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=96=87=E8=87=A3?= Date: Sat, 31 Jan 2026 22:21:55 +0800 Subject: [PATCH] Optimize code: replace pthread_mutex with os_unfair_lock, fix typos, improve uniqueId generation --- Sources/Core/QTEventBus.m | 93 ++++++++++++++++------------- Sources/Core/QTEventBusCollection.m | 50 ++++++++-------- 2 files changed, 78 insertions(+), 65 deletions(-) diff --git a/Sources/Core/QTEventBus.m b/Sources/Core/QTEventBus.m index c40236c..cf19ffe 100644 --- a/Sources/Core/QTEventBus.m +++ b/Sources/Core/QTEventBus.m @@ -7,22 +7,28 @@ // #import "QTEventBus.h" -#import +#import #import #import "NSObject+QTEventBus.h" #import "QTEventBusCollection.h" #import "NSNotification+QTEvent.h" #import "NSObject+QTEventBus_Private.h" -static inline NSString * __generateUnqiueKey(Class cls,NSString * eventType){ +static inline NSString * __generateUniqueKey(Class cls, NSString * eventType){ Class targetClass = [cls respondsToSelector:@selector(eventClass)] ? [cls eventClass] : cls; if (eventType) { - return [NSString stringWithFormat:@"%@_of_%@",eventType,NSStringFromClass(targetClass)]; - }else{ + return [NSString stringWithFormat:@"%@_of_%@", eventType, NSStringFromClass(targetClass)]; + } else { return NSStringFromClass(targetClass); } } +static inline NSString * __generateUniqueId(void) { + u_int64_t timestamp = (u_int64_t)([[NSDate date] timeIntervalSince1970] * 1000000); + u_int32_t random = arc4random(); + return [NSString stringWithFormat:@"%llu_%u", timestamp, random]; +} + /** 内存中保存的监听者 */ @@ -35,13 +41,13 @@ - (instancetype)initWithEventBus:(QTEventBus *)eventBus @property (strong, nonatomic) NSObject * lifeTimeTracker; -@property (strong, nonatomic) dispatch_queue_t queue; +@property (assign, nonatomic) dispatch_queue_t queue; @property (strong, nonatomic) NSMutableArray * eventSubTypes; @property (strong, nonatomic) QTEventBus * eventBus; -@property (copy, nonatomic) void(^hander)(__kindof NSObject *); +@property (copy, nonatomic) void(^handler)(__kindof NSObject *); @end @@ -55,7 +61,7 @@ @interface _QTEventSubscriber: NSObject @property (copy, nonatomic) void (^handler)(__kindof NSObject *); -@property (strong, nonatomic) dispatch_queue_t queue; +@property (assign, nonatomic) dispatch_queue_t queue; @property (copy, nonatomic) NSString * uniqueId; @@ -144,7 +150,7 @@ - (void)dispose{ @interface QTEventBus(){ - pthread_mutex_t _accessLock; + os_unfair_lock_t _accessLock; } @property (copy, nonatomic) NSString * prefix; @@ -153,7 +159,7 @@ @interface QTEventBus(){ @property (strong, nonatomic) dispatch_queue_t publishQueue; -@property (strong, nonatomic) NSMutableDictionary * notificationTracker; +@property (strong, nonatomic) NSMutableDictionary * notificationTracker; @end @@ -174,17 +180,17 @@ - (instancetype)init{ _collection = [[QTEventBusCollection alloc] init]; _publishQueue = dispatch_queue_create("com.eventbus.publish.queue", DISPATCH_QUEUE_SERIAL); _notificationTracker = [[NSMutableDictionary alloc] init]; - pthread_mutex_init(&_accessLock, NULL); + _accessLock = OS_UNFAIR_LOCK_INIT; } return self; } - (void)lockAndDo:(void(^)(void))block{ + os_unfair_lock_lock(_accessLock); @try{ - pthread_mutex_lock(&_accessLock); block(); }@finally{ - pthread_mutex_unlock(&_accessLock); + os_unfair_lock_unlock(_accessLock); } } @@ -192,14 +198,15 @@ - (void)lockAndDo:(void(^)(void))block{ - (id)_createNewSubscriber:(QTEventSubscriberMaker *)maker{ - if (!maker.hander) { + if (!maker.handler) { return nil; } + NSMutableArray * tokens; if (maker.eventSubTypes.count == 0) {//一级事件 _QTEventToken * token = [self _addSubscriberWithMaker:maker eventType:nil]; return token; } - NSMutableArray * tokens = [[NSMutableArray alloc] init]; + tokens = [[NSMutableArray alloc] initWithCapacity:maker.eventSubTypes.count]; for (NSString * eventType in maker.eventSubTypes) { _QTEventToken * token = [self _addSubscriberWithMaker:maker eventType:eventType]; [tokens addObject:token]; @@ -211,10 +218,12 @@ - (void)lockAndDo:(void(^)(void))block{ - (void)_addNotificationObserverIfNeeded:(NSString *)name{ if (!name) { return; } [self lockAndDo:^{ - if ([self.notificationTracker objectForKey:name]) { + NSNumber * count = self.notificationTracker[name]; + if (count && count.integerValue > 0) { + self.notificationTracker[name] = @(count.integerValue + 1); return; } - [self.notificationTracker setObject:@(1) forKey:name]; + self.notificationTracker[name] = @(1); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification:) name:name object:nil]; }]; } @@ -222,6 +231,11 @@ - (void)_addNotificationObserverIfNeeded:(NSString *)name{ - (void)_removeNotificationObserver:(NSString *)name{ if (!name) { return; } [self lockAndDo:^{ + NSNumber * count = self.notificationTracker[name]; + if (count && count.integerValue > 1) { + self.notificationTracker[name] = @(count.integerValue - 1); + return; + } [self.notificationTracker removeObjectForKey:name]; @try{ [[NSNotificationCenter defaultCenter] removeObserver:self name:name object:nil]; @@ -232,12 +246,12 @@ - (void)_removeNotificationObserver:(NSString *)name{ - (_QTEventToken *)_addSubscriberWithMaker:(QTEventSubscriberMaker *)maker eventType:(NSString *)eventType{ __weak typeof(self) weakSelf = self; - NSString * eventKey = __generateUnqiueKey(maker.eventClass, eventType); + NSString * eventKey = __generateUniqueKey(maker.eventClass, eventType); NSString * groupId = [self.prefix stringByAppendingString:eventKey]; - NSString * uniqueId = [groupId stringByAppendingString:@([NSDate date].timeIntervalSince1970).stringValue]; + NSString * uniqueId = [groupId stringByAppendingString:__generateUniqueId()]; _QTEventToken * token = [[_QTEventToken alloc] initWithKey:uniqueId]; - BOOL isCFNotifiction = (maker.eventClass == [NSNotification class]); - if (eventType && isCFNotifiction) { + BOOL isNSNotification = (maker.eventClass == [NSNotification class]); + if (eventType && isNSNotification) { [self _addNotificationObserverIfNeeded:eventType]; } token.onDispose = ^(NSString *uniqueId) { @@ -246,14 +260,14 @@ - (_QTEventToken *)_addSubscriberWithMaker:(QTEventSubscriberMaker *)maker event return; } BOOL empty = [strongSelf.collection removeUniqueId:uniqueId ofKey:groupId]; - if (empty && isCFNotifiction) { + if (empty && isNSNotification) { [strongSelf _removeNotificationObserver:eventType]; } }; //创建监听者 _QTEventSubscriber * subscriber = [[_QTEventSubscriber alloc] init]; subscriber.queue = maker.queue; - subscriber.handler = maker.hander; + subscriber.handler = maker.handler; subscriber.uniqueId = uniqueId; if (maker.lifeTimeTracker) { [maker.lifeTimeTracker.eb_disposeBag addToken:token]; @@ -273,8 +287,8 @@ - (_QTEventToken *)_addSubscriberWithMaker:(QTEventSubscriberMaker *)maker event return [[QTEventSubscriberMaker alloc] initWithEventBus:self eventClass:eventClass]; } -- (void)receiveNotification:(NSNotification *)notificaion{ - [self dispatch:notificaion]; +- (void)receiveNotification:(NSNotification *)notification{ + [self dispatch:notification]; } - (void)dispatch:(id)event{ @@ -284,11 +298,11 @@ - (void)dispatch:(id)event{ NSString * eventSubType = [event respondsToSelector:@selector(eventSubType)] ? [event eventSubType] : nil; if (eventSubType) { //二级事件 - NSString * key = __generateUnqiueKey(event.class, eventSubType); + NSString * key = __generateUniqueKey(event.class, eventSubType); [self _publishKey:key event:event]; } //一级事件 - NSString * key = __generateUnqiueKey(event.class, nil); + NSString * key = __generateUniqueKey(event.class, nil); [self _publishKey:key event:event]; } @@ -315,18 +329,17 @@ - (void)_publishKey:(NSString *)eventKey event:(NSObject *)event{ return; } for (_QTEventSubscriber * subscriber in subscribers) { - if (subscriber.queue) { //异步分发 + void(^handler)(NSObject *) = subscriber.handler; + if (!handler) { + continue; + } + if (subscriber.queue) { dispatch_async(subscriber.queue, ^{ - if (subscriber.handler) { - subscriber.handler(event); - } + handler(event); }); - }else{ //同步分发 - if (subscriber.handler) { - subscriber.handler(event); - } + } else { + handler(event); } - } } @@ -351,8 +364,8 @@ - (instancetype)initWithEventBus:(QTEventBus *)eventBus return self; } -- (id)next:(QTEventNextBlock)hander{ - return self.next(hander); +- (id)next:(QTEventNextBlock)block{ + return self.next(block); } - (QTEventSubscriberMaker *)atQueue:(dispatch_queue_t)queue{ @@ -396,12 +409,10 @@ - (QTEventSubscriberMaker *)ofSubType:(NSString *)eventType{ } - (id(^)(void(^)(id event)))next{ - return ^id(void(^hander)(__kindof NSObject * event)){ - self.hander = hander; + return ^id(void(^block)(__kindof NSObject * event)){ + self.handler = block; return [self.eventBus _createNewSubscriber:self]; }; } @end - - diff --git a/Sources/Core/QTEventBusCollection.m b/Sources/Core/QTEventBusCollection.m index 74a4c6b..19f2fa3 100644 --- a/Sources/Core/QTEventBusCollection.m +++ b/Sources/Core/QTEventBusCollection.m @@ -7,7 +7,7 @@ // #import "QTEventBusCollection.h" -#include +#include @class _QTEventBusLinkNode; /** @@ -73,10 +73,10 @@ - (BOOL)isEmpty{ */ - (void)removeNodeForId:(NSString *)uniqueId{ //不存在 - if (![_registeredNodeTable objectForKey:uniqueId]) { + _QTEventBusLinkNode * node = [_registeredNodeTable objectForKey:uniqueId]; + if (!node) { return; } - _QTEventBusLinkNode * node = [_registeredNodeTable objectForKey:uniqueId]; if (node == _head) { _head = _head.next; } @@ -87,8 +87,12 @@ - (void)removeNodeForId:(NSString *)uniqueId{ _QTEventBusLinkNode * nextNode = node.next; node.next = nil; node.previous = nil; - previousNode.next = nextNode; - nextNode.previous = previousNode; + if (previousNode) { + previousNode.next = nextNode; + } + if (nextNode) { + nextNode.previous = previousNode; + } [_registeredNodeTable removeObjectForKey:uniqueId]; } @@ -132,17 +136,17 @@ - (NSArray *)toArray{ } pointer = pointer.next; } - return [[NSArray alloc] initWithArray:array]; + return [array copy]; } @end @interface QTEventBusCollection(){ - pthread_mutex_t _accessLock; + os_unfair_lock_t _accessLock; } -@property (strong, nonatomic) NSMutableDictionary * linkListTable;//记录key->链表的头 +@property (strong, nonatomic) NSMutableDictionary * linkListTable; @end @@ -152,41 +156,39 @@ @implementation QTEventBusCollection - (instancetype)init{ if (self = [super init]) { _linkListTable = [[NSMutableDictionary alloc] init]; - pthread_mutex_init(&_accessLock, NULL); + _accessLock = OS_UNFAIR_LOCK_INIT; } return self; } - (void)lockAndDo:(void(^)(void))block{ + os_unfair_lock_lock(_accessLock); @try{ - pthread_mutex_lock(&_accessLock); block(); }@finally{ - pthread_mutex_unlock(&_accessLock); + os_unfair_lock_unlock(_accessLock); } } - (id)lockAndFetch:(id(^)(void))block{ - id result; + os_unfair_lock_lock(_accessLock); @try{ - pthread_mutex_lock(&_accessLock); - result = block(); + return block(); }@finally{ - pthread_mutex_unlock(&_accessLock); + os_unfair_lock_unlock(_accessLock); } - return result; } - (void)addObject:(id)object forKey:(NSString *)key{ NSString * nodeUniqueKey = [object valueUniqueId]; [self lockAndDo:^{ - _QTEventBusLinkList * linkList = [self.linkListTable objectForKey:key]; + _QTEventBusLinkList * linkList = self.linkListTable[key]; _QTEventBusLinkNode * updateNode = [[_QTEventBusLinkNode alloc] initWithValue:object uniqueId:nodeUniqueKey]; if (!linkList) { linkList = [[_QTEventBusLinkList alloc] initWithNode:updateNode]; - [self.linkListTable setObject:linkList forKey:key]; - }else{ + self.linkListTable[key] = linkList; + } else { [linkList appendNode:updateNode]; } }]; @@ -194,7 +196,7 @@ - (void)addObject:(id)object forKey:(NSString *)key{ - (BOOL)removeUniqueId:(NSString *)uniqueId ofKey:(NSString *)key{ NSNumber * result = [self lockAndFetch:^id{ - _QTEventBusLinkList * linkList = [self.linkListTable objectForKey:key]; + _QTEventBusLinkList * linkList = self.linkListTable[key]; [linkList removeNodeForId:uniqueId]; if (linkList.isEmpty) { [self.linkListTable removeObjectForKey:key]; @@ -208,11 +210,11 @@ - (BOOL)removeUniqueId:(NSString *)uniqueId ofKey:(NSString *)key{ 返回一组值 */ - (NSArray *)objectsForKey:(NSString *)key{ - NSArray * arrary = [self lockAndFetch:^id{ - _QTEventBusLinkList * linkList = [self.linkListTable objectForKey:key]; - return linkList.toArray; + NSArray * array = [self lockAndFetch:^id{ + _QTEventBusLinkList * linkList = self.linkListTable[key]; + return [linkList toArray]; }]; - return arrary; + return array; } @end