From e78625281f116c4178cf049c2d2e72fd8435b9ec Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Thu, 4 Mar 2021 12:53:42 +0800 Subject: [PATCH] fix:iOS Runloop cannot exit and other issues --- .../doric/src/main/java/pub/doric/DoricContext.java | 1 + doric-iOS/Devkit/Classes/DoricDev.m | 8 ++++---- doric-iOS/Devkit/Classes/DoricRemoteJSExecutor.m | 12 ++++++++---- doric-iOS/Devkit/Classes/DoricWSClient.m | 1 + doric-iOS/Pod/Classes/DoricContext.m | 3 +++ doric-iOS/Pod/Classes/Engine/DoricJSEngine.m | 3 +++ 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/doric-android/doric/src/main/java/pub/doric/DoricContext.java b/doric-android/doric/src/main/java/pub/doric/DoricContext.java index 7e81d911..4e5b0057 100644 --- a/doric-android/doric/src/main/java/pub/doric/DoricContext.java +++ b/doric-android/doric/src/main/java/pub/doric/DoricContext.java @@ -212,6 +212,7 @@ public class DoricContext { this.script = script; this.mRootNode.setId(""); this.mRootNode.clearSubModel(); + this.mRootNode.getView().removeAllViews(); getDriver().createContext(mContextId, script, source); init(this.extra); callEntity(DoricConstant.DORIC_ENTITY_CREATE); diff --git a/doric-iOS/Devkit/Classes/DoricDev.m b/doric-iOS/Devkit/Classes/DoricDev.m index 180ae35c..03fca90a 100644 --- a/doric-iOS/Devkit/Classes/DoricDev.m +++ b/doric-iOS/Devkit/Classes/DoricDev.m @@ -205,9 +205,9 @@ - (void)startDebugging:(NSString *)source { [self.wsClient sendToDebugger:@"DEBUG_RES" payload:@{ @"contextId": context.contextId }]; - self.debuggable = [[DoricContextDebuggable alloc] initWithWSClient:self.wsClient context:context]; - [self.debuggable startDebug]; dispatch_async(dispatch_get_main_queue(), ^{ + self.debuggable = [[DoricContextDebuggable alloc] initWithWSClient:self.wsClient context:context]; + [self.debuggable startDebug]; for (id callback in self.callbacks) { [callback onStartDebugging:context]; } @@ -224,9 +224,9 @@ - (void)stopDebugging:(BOOL)resume { [self.wsClient sendToDebugger:@"DEBUG_STOP" payload:@{ @"msg": @"Stop debugging" }]; - [self.debuggable stopDebug:resume]; - self.debuggable = nil; dispatch_async(dispatch_get_main_queue(), ^{ + [self.debuggable stopDebug:resume]; + self.debuggable = nil; for (id callback in self.callbacks) { [callback onStopDebugging]; } diff --git a/doric-iOS/Devkit/Classes/DoricRemoteJSExecutor.m b/doric-iOS/Devkit/Classes/DoricRemoteJSExecutor.m index f59db09a..cfe78e02 100644 --- a/doric-iOS/Devkit/Classes/DoricRemoteJSExecutor.m +++ b/doric-iOS/Devkit/Classes/DoricRemoteJSExecutor.m @@ -52,6 +52,7 @@ @interface DoricRemoteJSExecutor () @property(nonatomic) NSInteger counter; @property(nonatomic, strong) NSMutableDictionary *semaphores; @property(nonatomic, strong) NSMutableDictionary *results; +@property(nonatomic, strong) JSContext *jsContext; @end @implementation DoricRemoteJSExecutor @@ -63,6 +64,7 @@ - (instancetype)initWithWSClient:(DoricWSClient *)wsClient { _semaphores = [NSMutableDictionary new]; _results = [NSMutableDictionary new]; _counter = 0; + _jsContext = [[JSContext alloc] init]; } return self; } @@ -128,7 +130,7 @@ - (JSValue *)invokeObject:(NSString *)objName method:(NSString *)funcName args:( dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); self.semaphores[@(callId)] = semaphore; self.invokingMethod = YES; - DoricLog(@"Lock %@",@(callId)); + DoricLog(@"Lock %@", @(callId)); DC_LOCK(semaphore); JSValue *result = self.results[@(callId)]; [self.results removeObjectForKey:@(callId)]; @@ -169,7 +171,9 @@ - (BOOL)interceptType:(NSString *)type command:(NSString *)cmd payload:(NSDictio NSString *name = payload[@"name"]; NSArray *argsArr = payload[@"arguments"]; id tmpBlk = self.blockMDic[name]; - if (argsArr.count == 0) { + if (!tmpBlk) { + DoricLog(@"Cannot find inject function:%@", name); + } else if (argsArr.count == 0) { ((Block0) tmpBlk)(); } else if (argsArr.count == 1) { ((Block1) tmpBlk)(argsArr[0]); @@ -187,12 +191,12 @@ - (BOOL)interceptType:(NSString *)type command:(NSString *)cmd payload:(NSDictio } else if ([cmd isEqualToString:@"invokeMethod"]) { NSNumber *callId = payload[@"callId"]; @try { - JSValue *value = [JSValue valueWithObject:payload[@"result"] inContext:nil]; + JSValue *value = [JSValue valueWithObject:payload[@"result"] inContext:self.jsContext]; self.results[callId] = value; } @catch (NSException *exception) { DoricLog(@"debugger ", NSStringFromSelector(_cmd), exception.reason); } @finally { - DoricLog(@"Unlock:%@",payload); + DoricLog(@"Unlock:%@", payload); dispatch_semaphore_t semaphore = self.semaphores[callId]; [self.semaphores removeObjectForKey:callId]; DC_UNLOCK(semaphore); diff --git a/doric-iOS/Devkit/Classes/DoricWSClient.m b/doric-iOS/Devkit/Classes/DoricWSClient.m index 243dd84b..22064e74 100644 --- a/doric-iOS/Devkit/Classes/DoricWSClient.m +++ b/doric-iOS/Devkit/Classes/DoricWSClient.m @@ -38,6 +38,7 @@ - (instancetype)initWithUrl:(NSString *)url { _interceptors = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory]; _websocket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:url]]; _websocket.delegate = self; + _websocket.delegateDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); [_websocket open]; } return self; diff --git a/doric-iOS/Pod/Classes/DoricContext.m b/doric-iOS/Pod/Classes/DoricContext.m index e8055b75..1495ab04 100644 --- a/doric-iOS/Pod/Classes/DoricContext.m +++ b/doric-iOS/Pod/Classes/DoricContext.m @@ -102,6 +102,9 @@ - (void)reload:(NSString *)script { [self.driver destroyContext:self.contextId]; self.rootNode.viewId = nil; [self.rootNode clearSubModel]; + [self.rootNode.view.subviews forEach:^(__kindof UIView *obj) { + [obj removeFromSuperview]; + }]; self.script = script; [self.driver createContext:self.contextId script:script source:self.source]; [self init:self.extra]; diff --git a/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m b/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m index b2fa01a8..04a1ceb1 100644 --- a/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m +++ b/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m @@ -103,6 +103,9 @@ - (instancetype)init { - (void)teardown { _destroyed = YES; + //To ensure runloop continue. + [self ensureRunOnJSThread:^{ + }]; } - (void)ensureRunOnJSThread:(dispatch_block_t)block {