iOS:JS operation use seperated thread
This commit is contained in:
parent
1830acf977
commit
81dfce17fb
@ -55,7 +55,7 @@ - (DoricRegistry *)registry {
|
|||||||
- (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArray *)args {
|
- (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArray *)args {
|
||||||
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
dispatch_async(self.jsExecutor.jsQueue, ^() {
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -64,7 +64,7 @@ - (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArr
|
|||||||
} @catch (NSException *exception) {
|
} @catch (NSException *exception) {
|
||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ - (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArr
|
|||||||
[array addObject:arg];
|
[array addObject:arg];
|
||||||
}
|
}
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
dispatch_async(self.jsExecutor.jsQueue, ^() {
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -85,7 +85,7 @@ - (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArr
|
|||||||
} @catch (NSException *exception) {
|
} @catch (NSException *exception) {
|
||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString
|
|||||||
arg = va_arg(args, JSValue *);
|
arg = va_arg(args, JSValue *);
|
||||||
}
|
}
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
dispatch_async(self.jsExecutor.jsQueue, ^() {
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -117,7 +117,7 @@ - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString
|
|||||||
} @catch (NSException *exception) {
|
} @catch (NSException *exception) {
|
||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString
|
|||||||
[array addObject:arg];
|
[array addObject:arg];
|
||||||
}
|
}
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
dispatch_async(self.jsExecutor.jsQueue, ^() {
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -139,14 +139,14 @@ - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString
|
|||||||
} @catch (NSException *exception) {
|
} @catch (NSException *exception) {
|
||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (DoricAsyncResult *)createContext:(NSString *)contextId script:(NSString *)script source:(NSString *)source {
|
- (DoricAsyncResult *)createContext:(NSString *)contextId script:(NSString *)script source:(NSString *)source {
|
||||||
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
dispatch_async(self.jsExecutor.jsQueue, ^() {
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -155,14 +155,14 @@ - (DoricAsyncResult *)createContext:(NSString *)contextId script:(NSString *)scr
|
|||||||
} @catch (NSException *exception) {
|
} @catch (NSException *exception) {
|
||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (DoricAsyncResult *)destroyContext:(NSString *)contextId {
|
- (DoricAsyncResult *)destroyContext:(NSString *)contextId {
|
||||||
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
dispatch_async(self.jsExecutor.jsQueue, ^() {
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -171,7 +171,7 @@ - (DoricAsyncResult *)destroyContext:(NSString *)contextId {
|
|||||||
} @catch (NSException *exception) {
|
} @catch (NSException *exception) {
|
||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ + (instancetype)instance {
|
|||||||
- (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArray *)args {
|
- (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArray *)args {
|
||||||
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
dispatch_async(self.jsExecutor.jsQueue, ^() {
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -65,7 +65,7 @@ - (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArr
|
|||||||
} @catch (NSException *exception) {
|
} @catch (NSException *exception) {
|
||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ - (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArr
|
|||||||
[array addObject:arg];
|
[array addObject:arg];
|
||||||
}
|
}
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
dispatch_async(self.jsExecutor.jsQueue, ^() {
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -94,7 +94,7 @@ - (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArr
|
|||||||
} @catch (NSException *exception) {
|
} @catch (NSException *exception) {
|
||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString
|
|||||||
arg = va_arg(args, JSValue *);
|
arg = va_arg(args, JSValue *);
|
||||||
}
|
}
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
dispatch_async(self.jsExecutor.jsQueue, ^() {
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -127,7 +127,7 @@ - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString
|
|||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
[self.jsExecutor.registry onException:exception inContext:[[DoricContextManager instance] getContext:contextId]];
|
[self.jsExecutor.registry onException:exception inContext:[[DoricContextManager instance] getContext:contextId]];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString
|
|||||||
[array addObject:arg];
|
[array addObject:arg];
|
||||||
}
|
}
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
dispatch_async(self.jsExecutor.jsQueue, ^() {
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -150,14 +150,14 @@ - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString
|
|||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
[self.jsExecutor.registry onException:exception inContext:[[DoricContextManager instance] getContext:contextId]];
|
[self.jsExecutor.registry onException:exception inContext:[[DoricContextManager instance] getContext:contextId]];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (DoricAsyncResult *)createContext:(NSString *)contextId script:(NSString *)script source:(NSString *)source {
|
- (DoricAsyncResult *)createContext:(NSString *)contextId script:(NSString *)script source:(NSString *)source {
|
||||||
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
dispatch_async(self.jsExecutor.jsQueue, ^() {
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -167,14 +167,14 @@ - (DoricAsyncResult *)createContext:(NSString *)contextId script:(NSString *)scr
|
|||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
[self.registry onException:exception inContext:[[DoricContextManager instance] getContext:contextId]];
|
[self.registry onException:exception inContext:[[DoricContextManager instance] getContext:contextId]];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (DoricAsyncResult *)destroyContext:(NSString *)contextId {
|
- (DoricAsyncResult *)destroyContext:(NSString *)contextId {
|
||||||
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
dispatch_async(self.jsExecutor.jsQueue, ^() {
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -184,7 +184,7 @@ - (DoricAsyncResult *)destroyContext:(NSString *)contextId {
|
|||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
[self.jsExecutor.registry onException:exception inContext:[[DoricContextManager instance] getContext:contextId]];
|
[self.jsExecutor.registry onException:exception inContext:[[DoricContextManager instance] getContext:contextId]];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
@property(nonatomic, strong) id <DoricJSExecutorProtocol> jsExecutor;
|
@property(nonatomic, strong) id <DoricJSExecutorProtocol> jsExecutor;
|
||||||
|
|
||||||
@property(nonatomic, strong) dispatch_queue_t jsQueue;
|
|
||||||
|
|
||||||
@property(nonatomic, strong) DoricRegistry *registry;
|
@property(nonatomic, strong) DoricRegistry *registry;
|
||||||
|
|
||||||
@ -45,6 +44,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
- (JSValue *)invokeDoricMethod:(NSString *)method arguments:(va_list)args;
|
- (JSValue *)invokeDoricMethod:(NSString *)method arguments:(va_list)args;
|
||||||
|
|
||||||
- (JSValue *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArray *)args;
|
- (JSValue *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArray *)args;
|
||||||
|
|
||||||
|
- (void)ensureRunOnJSThread:(dispatch_block_t)block;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -45,13 +45,16 @@ @interface DoricJSEngine ()
|
|||||||
@property(nonatomic, strong) NSMutableDictionary *timers;
|
@property(nonatomic, strong) NSMutableDictionary *timers;
|
||||||
@property(nonatomic, strong) DoricBridgeExtension *bridgeExtension;
|
@property(nonatomic, strong) DoricBridgeExtension *bridgeExtension;
|
||||||
@property(nonatomic, strong) NSDictionary *innerEnvironmentDictionary;
|
@property(nonatomic, strong) NSDictionary *innerEnvironmentDictionary;
|
||||||
|
@property(nonatomic, strong) NSThread *jsThread;
|
||||||
|
@property(nonatomic, assign) BOOL destroyed;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation DoricJSEngine
|
@implementation DoricJSEngine
|
||||||
|
|
||||||
- (instancetype)init {
|
- (instancetype)init {
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
_jsQueue = dispatch_queue_create("doric.jsengine", DISPATCH_QUEUE_SERIAL);
|
_jsThread = [[NSThread alloc] initWithTarget:self selector:@selector(threadRun) object:nil];
|
||||||
|
[_jsThread start];
|
||||||
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
|
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
|
||||||
struct utsname systemInfo;
|
struct utsname systemInfo;
|
||||||
uname(&systemInfo);
|
uname(&systemInfo);
|
||||||
@ -72,7 +75,7 @@ - (instancetype)init {
|
|||||||
@"deviceBrand": @"Apple",
|
@"deviceBrand": @"Apple",
|
||||||
@"deviceModel": platform,
|
@"deviceModel": platform,
|
||||||
};
|
};
|
||||||
dispatch_async(_jsQueue, ^() {
|
[self ensureRunOnJSThread:^() {
|
||||||
self.timers = [[NSMutableDictionary alloc] init];
|
self.timers = [[NSMutableDictionary alloc] init];
|
||||||
self.registry = [[DoricRegistry alloc] init];
|
self.registry = [[DoricRegistry alloc] init];
|
||||||
self.bridgeExtension = [DoricBridgeExtension new];
|
self.bridgeExtension = [DoricBridgeExtension new];
|
||||||
@ -80,11 +83,36 @@ - (instancetype)init {
|
|||||||
[self initJSEngine];
|
[self initJSEngine];
|
||||||
[self initJSExecutor];
|
[self initJSExecutor];
|
||||||
[self initDoricEnvironment];
|
[self initDoricEnvironment];
|
||||||
});
|
}];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
_destroyed = YES;
|
||||||
|
};
|
||||||
|
|
||||||
|
- (void)ensureRunOnJSThread:(dispatch_block_t)block {
|
||||||
|
if (NSThread.currentThread == _jsThread) {
|
||||||
|
block();
|
||||||
|
} else {
|
||||||
|
[self performSelector:@selector(ensureRunOnJSThread:)
|
||||||
|
onThread:_jsThread
|
||||||
|
withObject:[block copy]
|
||||||
|
waitUntilDone:NO];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)threadRun {
|
||||||
|
[[NSRunLoop currentRunLoop] addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
|
||||||
|
[NSThread currentThread].name = @"doric.js.engine";
|
||||||
|
while (!_destroyed) {
|
||||||
|
@autoreleasepool {
|
||||||
|
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)initJSEngine {
|
- (void)initJSEngine {
|
||||||
[self.registry registerMonitor:[DoricDefaultMonitor new]];
|
[self.registry registerMonitor:[DoricDefaultMonitor new]];
|
||||||
self.jsExecutor = [DoricJSCoreExecutor new];
|
self.jsExecutor = [DoricJSCoreExecutor new];
|
||||||
@ -234,7 +262,7 @@ - (void)callbackTimer:(NSTimer *)timer {
|
|||||||
NSDictionary *userInfo = timer.userInfo;
|
NSDictionary *userInfo = timer.userInfo;
|
||||||
NSNumber *timerId = [userInfo valueForKey:@"timerId"];
|
NSNumber *timerId = [userInfo valueForKey:@"timerId"];
|
||||||
NSNumber *repeat = [userInfo valueForKey:@"repeat"];
|
NSNumber *repeat = [userInfo valueForKey:@"repeat"];
|
||||||
dispatch_async(self.jsQueue, ^() {
|
[self ensureRunOnJSThread:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
@try {
|
@try {
|
||||||
[self invokeDoricMethod:DORIC_TIMER_CALLBACK, timerId, nil];
|
[self invokeDoricMethod:DORIC_TIMER_CALLBACK, timerId, nil];
|
||||||
@ -246,6 +274,6 @@ - (void)callbackTimer:(NSTimer *)timer {
|
|||||||
if (![repeat boolValue]) {
|
if (![repeat boolValue]) {
|
||||||
[self.timers removeObjectForKey:[timerId stringValue]];
|
[self.timers removeObjectForKey:[timerId stringValue]];
|
||||||
}
|
}
|
||||||
});
|
}];
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
Reference in New Issue
Block a user