iOS: add thread-safe handling for JSDispatcher

This commit is contained in:
pengfei.zhou 2023-05-09 11:52:13 +08:00 committed by jingpeng
parent 542f73e0fd
commit d92ce26248

View File

@ -22,42 +22,57 @@
@interface DoricJSDispatcher () @interface DoricJSDispatcher ()
@property(nonatomic, strong) NSMutableArray <DoricAsyncResult *(^)(void)> *blocks; @property(nonatomic, strong) NSMutableArray <DoricAsyncResult *(^)(void)> *blocks;
@property(nonatomic, assign) BOOL consuming; @property(nonatomic, assign) BOOL consuming;
@property(nonatomic, strong) dispatch_queue_t syncQueue;
@end @end
@implementation DoricJSDispatcher @implementation DoricJSDispatcher
- (instancetype)init {
if (self = [super init]) {
_syncQueue = dispatch_queue_create("DoricJSDispatcher", DISPATCH_QUEUE_CONCURRENT);
}
return self;
}
- (void)dispatch:(DoricAsyncResult *(^)(void))block { - (void)dispatch:(DoricAsyncResult *(^)(void))block {
if (!self.blocks) { dispatch_barrier_async(self.syncQueue, ^{
self.blocks = [@[block] mutableCopy]; if (!self.blocks) {
} else { self.blocks = [@[block] mutableCopy];
if (self.blocks.count > 0) { } else {
[self.blocks removeAllObjects]; 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 { - (void)consume {
DoricAsyncResult *(^block )(void) = self.blocks.lastObject; dispatch_barrier_async(self.syncQueue, ^{
if (block) { DoricAsyncResult *(^block )(void) = self.blocks.lastObject;
self.consuming = YES; if (block) {
[self.blocks removeLastObject]; self.consuming = YES;
DoricAsyncResult *result = block(); [self.blocks removeLastObject];
__weak typeof(self) __self = self; DoricAsyncResult *result = block();
result.finishCallback = ^{ __weak typeof(self) __self = self;
dispatch_async(dispatch_get_main_queue(), ^{ result.finishCallback = ^{
__strong typeof(__self) self = __self; dispatch_async(dispatch_get_main_queue(), ^{
[self consume]; __strong typeof(__self) self = __self;
}); [self consume];
}; });
} else { };
self.consuming = NO; } else {
} self.consuming = NO;
}
});
} }
- (void)clear { - (void)clear {
[self.blocks removeAllObjects]; dispatch_barrier_async(self.syncQueue, ^{
[self.blocks removeAllObjects];
});
} }
@end @end