iOS: add thread-safe handling for JSDispatcher
This commit is contained in:
parent
542f73e0fd
commit
d92ce26248
@ -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
|
||||||
|
Reference in New Issue
Block a user