From d92ce262488765ce87ed4ec1f90894a9669beb04 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Tue, 9 May 2023 11:52:13 +0800 Subject: [PATCH] iOS: add thread-safe handling for JSDispatcher --- .../Pod/Classes/Util/DoricJSDispatcher.m | 67 ++++++++++++------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/doric-iOS/Pod/Classes/Util/DoricJSDispatcher.m b/doric-iOS/Pod/Classes/Util/DoricJSDispatcher.m index 2d2620f4..118e1550 100644 --- a/doric-iOS/Pod/Classes/Util/DoricJSDispatcher.m +++ b/doric-iOS/Pod/Classes/Util/DoricJSDispatcher.m @@ -22,42 +22,57 @@ @interface DoricJSDispatcher () @property(nonatomic, strong) NSMutableArray *blocks; @property(nonatomic, assign) BOOL consuming; +@property(nonatomic, strong) dispatch_queue_t syncQueue; @end @implementation DoricJSDispatcher +- (instancetype)init { + if (self = [super init]) { + _syncQueue = dispatch_queue_create("DoricJSDispatcher", DISPATCH_QUEUE_CONCURRENT); + } + return self; +} + - (void)dispatch:(DoricAsyncResult *(^)(void))block { - if (!self.blocks) { - self.blocks = [@[block] mutableCopy]; - } else { - if (self.blocks.count > 0) { - [self.blocks removeAllObjects]; + dispatch_barrier_async(self.syncQueue, ^{ + if (!self.blocks) { + self.blocks = [@[block] mutableCopy]; + } else { + if (self.blocks.count > 0) { + [self.blocks removeAllObjects]; + } + [self.blocks insertObject:block atIndex:0]; } - [self.blocks insertObject:block atIndex:0]; - } - if (!self.consuming) { - [self consume]; - } + if (!self.consuming) { + [self consume]; + } + }); + } - (void)consume { - DoricAsyncResult *(^block )(void) = self.blocks.lastObject; - if (block) { - self.consuming = YES; - [self.blocks removeLastObject]; - DoricAsyncResult *result = block(); - __weak typeof(self) __self = self; - result.finishCallback = ^{ - dispatch_async(dispatch_get_main_queue(), ^{ - __strong typeof(__self) self = __self; - [self consume]; - }); - }; - } else { - self.consuming = NO; - } + dispatch_barrier_async(self.syncQueue, ^{ + DoricAsyncResult *(^block )(void) = self.blocks.lastObject; + if (block) { + self.consuming = YES; + [self.blocks removeLastObject]; + DoricAsyncResult *result = block(); + __weak typeof(self) __self = self; + result.finishCallback = ^{ + dispatch_async(dispatch_get_main_queue(), ^{ + __strong typeof(__self) self = __self; + [self consume]; + }); + }; + } else { + self.consuming = NO; + } + }); } - (void)clear { - [self.blocks removeAllObjects]; + dispatch_barrier_async(self.syncQueue, ^{ + [self.blocks removeAllObjects]; + }); } @end