feat:fix iOS memory leak in debugging
This commit is contained in:
parent
b972cce1cd
commit
627f323ae3
@ -41,14 +41,12 @@ public class DoricDebugDriver implements IDoricDriver {
|
|||||||
private final DoricDebugJSEngine doricDebugJSEngine;
|
private final DoricDebugJSEngine doricDebugJSEngine;
|
||||||
private final ExecutorService mBridgeExecutor;
|
private final ExecutorService mBridgeExecutor;
|
||||||
private final Handler mUIHandler;
|
private final Handler mUIHandler;
|
||||||
private final Handler mJSHandler;
|
|
||||||
private String theContextId = null;
|
private String theContextId = null;
|
||||||
|
|
||||||
public DoricDebugDriver(WSClient wsClient) {
|
public DoricDebugDriver(WSClient wsClient) {
|
||||||
doricDebugJSEngine = new DoricDebugJSEngine(wsClient);
|
doricDebugJSEngine = new DoricDebugJSEngine(wsClient);
|
||||||
mBridgeExecutor = Executors.newCachedThreadPool();
|
mBridgeExecutor = Executors.newCachedThreadPool();
|
||||||
mUIHandler = new Handler(Looper.getMainLooper());
|
mUIHandler = new Handler(Looper.getMainLooper());
|
||||||
mJSHandler = doricDebugJSEngine.getJSHandler();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -64,7 +62,7 @@ public class DoricDebugDriver implements IDoricDriver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args) {
|
public AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args) {
|
||||||
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<JSDecoder>() {
|
return AsyncCall.ensureRunInExecutor(mBridgeExecutor, new Callable<JSDecoder>() {
|
||||||
@Override
|
@Override
|
||||||
public JSDecoder call() {
|
public JSDecoder call() {
|
||||||
try {
|
try {
|
||||||
@ -80,11 +78,10 @@ public class DoricDebugDriver implements IDoricDriver {
|
|||||||
@Override
|
@Override
|
||||||
public <T> AsyncResult<T> asyncCall(Callable<T> callable, ThreadMode threadMode) {
|
public <T> AsyncResult<T> asyncCall(Callable<T> callable, ThreadMode threadMode) {
|
||||||
switch (threadMode) {
|
switch (threadMode) {
|
||||||
case JS:
|
|
||||||
return AsyncCall.ensureRunInHandler(mJSHandler, callable);
|
|
||||||
case UI:
|
case UI:
|
||||||
return AsyncCall.ensureRunInHandler(mUIHandler, callable);
|
return AsyncCall.ensureRunInHandler(mUIHandler, callable);
|
||||||
case INDEPENDENT:
|
case INDEPENDENT:
|
||||||
|
case JS:
|
||||||
default:
|
default:
|
||||||
return AsyncCall.ensureRunInExecutor(mBridgeExecutor, callable);
|
return AsyncCall.ensureRunInExecutor(mBridgeExecutor, callable);
|
||||||
}
|
}
|
||||||
@ -92,7 +89,7 @@ public class DoricDebugDriver implements IDoricDriver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncResult<Boolean> createContext(final String contextId, final String script, final String source) {
|
public AsyncResult<Boolean> createContext(final String contextId, final String script, final String source) {
|
||||||
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() {
|
return AsyncCall.ensureRunInExecutor(mBridgeExecutor, new Callable<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean call() {
|
public Boolean call() {
|
||||||
try {
|
try {
|
||||||
@ -108,7 +105,7 @@ public class DoricDebugDriver implements IDoricDriver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncResult<Boolean> destroyContext(final String contextId) {
|
public AsyncResult<Boolean> destroyContext(final String contextId) {
|
||||||
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() {
|
return AsyncCall.ensureRunInExecutor(mBridgeExecutor, new Callable<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean call() {
|
public Boolean call() {
|
||||||
try {
|
try {
|
||||||
|
@ -11,16 +11,21 @@ import org.json.JSONObject;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import pub.doric.devkit.WSClient;
|
import pub.doric.devkit.WSClient;
|
||||||
|
|
||||||
public class RemoteJSExecutor implements WSClient.Interceptor {
|
public class RemoteJSExecutor implements WSClient.Interceptor {
|
||||||
private final Map<String, JavaFunction> globalFunctions = new HashMap<>();
|
private final Map<String, JavaFunction> globalFunctions = new HashMap<>();
|
||||||
private JSDecoder temp;
|
|
||||||
private final WSClient wsClient;
|
private final WSClient wsClient;
|
||||||
private final Thread currentThread;
|
private final Thread currentThread;
|
||||||
|
|
||||||
|
private final AtomicInteger callIdCounter = new AtomicInteger();
|
||||||
|
|
||||||
|
private Map<Integer, Thread> mThreads = new HashMap<>();
|
||||||
|
private Map<Integer, JSDecoder> mResults = new HashMap<>();
|
||||||
|
|
||||||
public RemoteJSExecutor(WSClient wsClient) {
|
public RemoteJSExecutor(WSClient wsClient) {
|
||||||
this.wsClient = wsClient;
|
this.wsClient = wsClient;
|
||||||
this.wsClient.addInterceptor(this);
|
this.wsClient.addInterceptor(this);
|
||||||
@ -63,6 +68,7 @@ public class RemoteJSExecutor implements WSClient.Interceptor {
|
|||||||
.put("value", javaValue.getValue())
|
.put("value", javaValue.getValue())
|
||||||
.toJSONObject());
|
.toJSONObject());
|
||||||
}
|
}
|
||||||
|
int callId = callIdCounter.incrementAndGet();
|
||||||
wsClient.sendToDebugger(
|
wsClient.sendToDebugger(
|
||||||
"invokeMethod",
|
"invokeMethod",
|
||||||
new JSONBuilder()
|
new JSONBuilder()
|
||||||
@ -70,11 +76,13 @@ public class RemoteJSExecutor implements WSClient.Interceptor {
|
|||||||
.put("objectName", objectName)
|
.put("objectName", objectName)
|
||||||
.put("functionName", functionName)
|
.put("functionName", functionName)
|
||||||
.put("values", jsonArray)
|
.put("values", jsonArray)
|
||||||
|
.put("callId", callId)
|
||||||
.put("hashKey", hashKey)
|
.put("hashKey", hashKey)
|
||||||
.toJSONObject());
|
.toJSONObject());
|
||||||
|
Thread thread = Thread.currentThread();
|
||||||
LockSupport.park(Thread.currentThread());
|
mThreads.put(callId, thread);
|
||||||
return temp;
|
LockSupport.park(thread);
|
||||||
|
return mResults.remove(callId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
@ -99,15 +107,16 @@ public class RemoteJSExecutor implements WSClient.Interceptor {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "invokeMethod": {
|
case "invokeMethod": {
|
||||||
|
int callId = payload.optInt("callId");
|
||||||
try {
|
try {
|
||||||
Object result = payload.opt("result");
|
Object result = payload.opt("result");
|
||||||
ValueBuilder vb = new ValueBuilder(result);
|
ValueBuilder vb = new ValueBuilder(result);
|
||||||
temp = new JSDecoder(vb.build());
|
mResults.put(callId, new JSDecoder(vb.build()));
|
||||||
System.out.println(result);
|
System.out.println(result);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
LockSupport.unpark(currentThread);
|
LockSupport.unpark(mThreads.remove(callId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -166,4 +166,11 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearSubModel() {
|
||||||
|
super.clearSubModel();
|
||||||
|
mChildNodes.clear();
|
||||||
|
mChildViewIds.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,13 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <DoricCore/Doric.h>
|
#import <DoricCore/Doric.h>
|
||||||
#import "DoricWSClient.h"
|
#import "DoricWSClient.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface DoricDebugDriver : NSObject <DoricDriverProtocol>
|
@interface DoricDebugDriver : NSObject <DoricDriverProtocol>
|
||||||
- (instancetype)initWithWSClient:(DoricWSClient *)wsClient;
|
- (instancetype)initWithWSClient:(DoricWSClient *)wsClient;
|
||||||
|
|
||||||
|
- (void)teardown;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -57,7 +57,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;
|
||||||
[self.jsExecutor ensureRunOnJSThread:^{
|
[self runInJSQueue:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -78,7 +78,7 @@ - (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArr
|
|||||||
[array addObject:arg];
|
[array addObject:arg];
|
||||||
}
|
}
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
[self.jsExecutor ensureRunOnJSThread:^{
|
[self runInJSQueue:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -110,7 +110,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;
|
||||||
[self.jsExecutor ensureRunOnJSThread:^{
|
[self runInJSQueue:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -132,7 +132,7 @@ - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString
|
|||||||
[array addObject:arg];
|
[array addObject:arg];
|
||||||
}
|
}
|
||||||
__weak typeof(self) _self = self;
|
__weak typeof(self) _self = self;
|
||||||
[self.jsExecutor ensureRunOnJSThread:^{
|
[self runInJSQueue:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -148,7 +148,7 @@ - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString
|
|||||||
- (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;
|
||||||
[self.jsExecutor ensureRunOnJSThread:^{
|
[self runInJSQueue:^{
|
||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
@ -164,7 +164,7 @@ - (DoricAsyncResult *)createContext:(NSString *)contextId script:(NSString *)scr
|
|||||||
- (DoricAsyncResult *)destroyContext:(NSString *)contextId {
|
- (DoricAsyncResult *)destroyContext:(NSString *)contextId {
|
||||||
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
DoricAsyncResult *ret = [[DoricAsyncResult alloc] init];
|
||||||
NSString *theContextId = self.theContextId;
|
NSString *theContextId = self.theContextId;
|
||||||
[self.jsExecutor ensureRunOnJSThread:^{
|
[self runInJSQueue:^{
|
||||||
@try {
|
@try {
|
||||||
if ([contextId isEqualToString:theContextId]) {
|
if ([contextId isEqualToString:theContextId]) {
|
||||||
[DoricDev.instance stopDebugging:NO];
|
[DoricDev.instance stopDebugging:NO];
|
||||||
@ -177,6 +177,12 @@ - (DoricAsyncResult *)destroyContext:(NSString *)contextId {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)runInJSQueue:(dispatch_block_t)block {
|
||||||
|
[self.jsExecutor ensureRunOnJSThread:^{
|
||||||
|
block();
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)ensureSyncInMainQueue:(dispatch_block_t)block {
|
- (void)ensureSyncInMainQueue:(dispatch_block_t)block {
|
||||||
if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(dispatch_get_main_queue())) == 0) {
|
if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(dispatch_get_main_queue())) == 0) {
|
||||||
block();
|
block();
|
||||||
@ -184,4 +190,12 @@ - (void)ensureSyncInMainQueue:(dispatch_block_t)block {
|
|||||||
dispatch_async(dispatch_get_main_queue(), block);
|
dispatch_async(dispatch_get_main_queue(), block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
[self.jsExecutor teardown];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)teardown {
|
||||||
|
[self.jsExecutor teardown];
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
@ -42,4 +42,21 @@ - (instancetype)initWithWSClient:(DoricWSClient *)wsClient {
|
|||||||
- (void)initJSEngine {
|
- (void)initJSEngine {
|
||||||
self.jsExecutor = [[DoricRemoteJSExecutor alloc] initWithWSClient:self.wsClient];
|
self.jsExecutor = [[DoricRemoteJSExecutor alloc] initWithWSClient:self.wsClient];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)teardown {
|
||||||
|
[super teardown];
|
||||||
|
if ([self.jsExecutor isKindOfClass:DoricRemoteJSExecutor.class]) {
|
||||||
|
[((DoricRemoteJSExecutor *) (self.jsExecutor)) teardown];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)ensureRunOnJSThread:(dispatch_block_t)block {
|
||||||
|
if ([self.jsExecutor isKindOfClass:DoricRemoteJSExecutor.class]
|
||||||
|
&& ((DoricRemoteJSExecutor *) (self.jsExecutor)).invokingMethod) {
|
||||||
|
NSThread *thread = [[NSThread alloc] initWithBlock:block];
|
||||||
|
[thread start];
|
||||||
|
} else {
|
||||||
|
[super ensureRunOnJSThread:block];
|
||||||
|
}
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
@ -32,6 +32,8 @@ @interface DoricContextDebuggable : NSObject
|
|||||||
@property(nonatomic, weak) DoricContext *doricContext;
|
@property(nonatomic, weak) DoricContext *doricContext;
|
||||||
@property(nonatomic, weak) id <DoricDriverProtocol> nativeDriver;
|
@property(nonatomic, weak) id <DoricDriverProtocol> nativeDriver;
|
||||||
@property(nonatomic, weak) DoricWSClient *wsClient;
|
@property(nonatomic, weak) DoricWSClient *wsClient;
|
||||||
|
@property(nonatomic, weak) DoricDebugDriver *debugDriver;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation DoricContextDebuggable
|
@implementation DoricContextDebuggable
|
||||||
@ -46,10 +48,12 @@ - (instancetype)initWithWSClient:(DoricWSClient *)client context:(DoricContext *
|
|||||||
|
|
||||||
- (void)startDebug {
|
- (void)startDebug {
|
||||||
[self.doricContext setDriver:[[DoricDebugDriver alloc] initWithWSClient:self.wsClient]];
|
[self.doricContext setDriver:[[DoricDebugDriver alloc] initWithWSClient:self.wsClient]];
|
||||||
|
self.debugDriver = self.doricContext.driver;
|
||||||
[self.doricContext reload:self.doricContext.script];
|
[self.doricContext reload:self.doricContext.script];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)stopDebug:(BOOL)resume {
|
- (void)stopDebug:(BOOL)resume {
|
||||||
|
[self.debugDriver teardown];
|
||||||
self.doricContext.driver = self.nativeDriver;
|
self.doricContext.driver = self.nativeDriver;
|
||||||
if (resume) {
|
if (resume) {
|
||||||
[self.doricContext reload:self.doricContext.script];
|
[self.doricContext reload:self.doricContext.script];
|
||||||
|
@ -27,7 +27,11 @@
|
|||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface DoricRemoteJSExecutor : NSObject <DoricJSExecutorProtocol>
|
@interface DoricRemoteJSExecutor : NSObject <DoricJSExecutorProtocol>
|
||||||
|
@property(nonatomic, assign) BOOL invokingMethod;
|
||||||
|
|
||||||
- (instancetype)initWithWSClient:(DoricWSClient *)wsClient;
|
- (instancetype)initWithWSClient:(DoricWSClient *)wsClient;
|
||||||
|
|
||||||
|
- (void)teardown;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -49,8 +49,9 @@ typedef NS_ENUM(NSUInteger, DoricJSRemoteArgType) {
|
|||||||
@interface DoricRemoteJSExecutor () <DoricWSClientInterceptor>
|
@interface DoricRemoteJSExecutor () <DoricWSClientInterceptor>
|
||||||
@property(nonatomic, weak) DoricWSClient *wsClient;
|
@property(nonatomic, weak) DoricWSClient *wsClient;
|
||||||
@property(nonatomic, strong) NSMutableDictionary <NSString *, id> *blockMDic;
|
@property(nonatomic, strong) NSMutableDictionary <NSString *, id> *blockMDic;
|
||||||
@property(nonatomic, strong) JSValue *temp;
|
@property(nonatomic) NSInteger counter;
|
||||||
@property(nonatomic, strong) dispatch_semaphore_t semaphore;
|
@property(nonatomic, strong) NSMutableDictionary <NSNumber *, dispatch_semaphore_t> *semaphores;
|
||||||
|
@property(nonatomic, strong) NSMutableDictionary <NSNumber *, JSValue *> *results;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation DoricRemoteJSExecutor
|
@implementation DoricRemoteJSExecutor
|
||||||
@ -59,7 +60,9 @@ - (instancetype)initWithWSClient:(DoricWSClient *)wsClient {
|
|||||||
_wsClient = wsClient;
|
_wsClient = wsClient;
|
||||||
[_wsClient addInterceptor:self];
|
[_wsClient addInterceptor:self];
|
||||||
_blockMDic = [NSMutableDictionary new];
|
_blockMDic = [NSMutableDictionary new];
|
||||||
_semaphore = dispatch_semaphore_create(0);
|
_semaphores = [NSMutableDictionary new];
|
||||||
|
_results = [NSMutableDictionary new];
|
||||||
|
_counter = 0;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -114,17 +117,23 @@ - (JSValue *)invokeObject:(NSString *)objName method:(NSString *)funcName args:(
|
|||||||
NSDictionary *dic = [self dicForArg:arg];
|
NSDictionary *dic = [self dicForArg:arg];
|
||||||
[argsMArr addObject:dic];
|
[argsMArr addObject:dic];
|
||||||
}
|
}
|
||||||
|
NSInteger callId = ++self.counter;
|
||||||
[self.wsClient sendToDebugger:@"invokeMethod" payload:@{
|
[self.wsClient sendToDebugger:@"invokeMethod" payload:@{
|
||||||
@"cmd": @"invokeMethod",
|
@"cmd": @"invokeMethod",
|
||||||
@"objectName": objName,
|
@"objectName": objName,
|
||||||
@"functionName": funcName,
|
@"functionName": funcName,
|
||||||
|
@"callId": @(callId),
|
||||||
@"values": [argsMArr copy]
|
@"values": [argsMArr copy]
|
||||||
}];
|
}];
|
||||||
|
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||||
DC_LOCK(self.semaphore);
|
self.semaphores[@(callId)] = semaphore;
|
||||||
|
self.invokingMethod = YES;
|
||||||
return self.temp;
|
DoricLog(@"Lock %@",@(callId));
|
||||||
|
DC_LOCK(semaphore);
|
||||||
|
JSValue *result = self.results[@(callId)];
|
||||||
|
[self.results removeObjectForKey:@(callId)];
|
||||||
|
self.invokingMethod = NO;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDictionary *)dicForArg:(id)arg {
|
- (NSDictionary *)dicForArg:(id)arg {
|
||||||
@ -161,32 +170,43 @@ - (BOOL)interceptType:(NSString *)type command:(NSString *)cmd payload:(NSDictio
|
|||||||
NSArray *argsArr = payload[@"arguments"];
|
NSArray *argsArr = payload[@"arguments"];
|
||||||
id tmpBlk = self.blockMDic[name];
|
id tmpBlk = self.blockMDic[name];
|
||||||
if (argsArr.count == 0) {
|
if (argsArr.count == 0) {
|
||||||
((Block0) tmpBlk)();
|
((Block0) tmpBlk)();
|
||||||
} else if (argsArr.count == 1) {
|
} else if (argsArr.count == 1) {
|
||||||
((Block1) tmpBlk)(argsArr[0]);
|
((Block1) tmpBlk)(argsArr[0]);
|
||||||
} else if (argsArr.count == 2) {
|
} else if (argsArr.count == 2) {
|
||||||
((Block2) tmpBlk)(argsArr[0], argsArr[1]);
|
((Block2) tmpBlk)(argsArr[0], argsArr[1]);
|
||||||
} else if (argsArr.count == 3) {
|
} else if (argsArr.count == 3) {
|
||||||
((Block3) tmpBlk)(argsArr[0], argsArr[1], argsArr[2]);
|
((Block3) tmpBlk)(argsArr[0], argsArr[1], argsArr[2]);
|
||||||
} else if (argsArr.count == 4) {
|
} else if (argsArr.count == 4) {
|
||||||
((Block4) tmpBlk)(argsArr[0], argsArr[1], argsArr[2], argsArr[3]);
|
((Block4) tmpBlk)(argsArr[0], argsArr[1], argsArr[2], argsArr[3]);
|
||||||
} else if (argsArr.count == 5) {
|
} else if (argsArr.count == 5) {
|
||||||
((Block5) tmpBlk)(argsArr[0], argsArr[1], argsArr[2], argsArr[3], argsArr[4]);
|
((Block5) tmpBlk)(argsArr[0], argsArr[1], argsArr[2], argsArr[3], argsArr[4]);
|
||||||
} else {
|
} else {
|
||||||
DoricLog(@"error:args to more than 5. args:%@", argsArr);
|
DoricLog(@"error:args to more than 5. args:%@", argsArr);
|
||||||
}
|
}
|
||||||
} else if ([cmd isEqualToString:@"invokeMethod"]) {
|
} else if ([cmd isEqualToString:@"invokeMethod"]) {
|
||||||
|
NSNumber *callId = payload[@"callId"];
|
||||||
@try {
|
@try {
|
||||||
self.temp = [JSValue valueWithObject:payload[@"result"] inContext:nil];
|
JSValue *value = [JSValue valueWithObject:payload[@"result"] inContext:nil];
|
||||||
|
self.results[callId] = value;
|
||||||
} @catch (NSException *exception) {
|
} @catch (NSException *exception) {
|
||||||
DoricLog(@"debugger ", NSStringFromSelector(_cmd), exception.reason);
|
DoricLog(@"debugger ", NSStringFromSelector(_cmd), exception.reason);
|
||||||
} @finally {
|
} @finally {
|
||||||
DC_UNLOCK(self.semaphore);
|
DoricLog(@"Unlock:%@",payload);
|
||||||
|
dispatch_semaphore_t semaphore = self.semaphores[callId];
|
||||||
|
[self.semaphores removeObjectForKey:callId];
|
||||||
|
DC_UNLOCK(semaphore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)teardown {
|
||||||
|
[self.blockMDic removeAllObjects];
|
||||||
|
[self.semaphores enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, dispatch_semaphore_t obj, BOOL *stop) {
|
||||||
|
DC_UNLOCK(obj);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -101,6 +101,7 @@ - (void)build:(CGSize)size {
|
|||||||
- (void)reload:(NSString *)script {
|
- (void)reload:(NSString *)script {
|
||||||
[self.driver destroyContext:self.contextId];
|
[self.driver destroyContext:self.contextId];
|
||||||
self.rootNode.viewId = nil;
|
self.rootNode.viewId = nil;
|
||||||
|
[self.rootNode clearSubModel];
|
||||||
self.script = script;
|
self.script = script;
|
||||||
[self.driver createContext:self.contextId script:script source:self.source];
|
[self.driver createContext:self.contextId script:script source:self.source];
|
||||||
[self init:self.extra];
|
[self init:self.extra];
|
||||||
|
@ -195,4 +195,8 @@ - (void)ensureSyncInMainQueue:(dispatch_block_t)block {
|
|||||||
dispatch_async(dispatch_get_main_queue(), block);
|
dispatch_async(dispatch_get_main_queue(), block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
[self.jsExecutor teardown];
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
@ -48,6 +48,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
- (void)ensureRunOnJSThread:(dispatch_block_t)block;
|
- (void)ensureRunOnJSThread:(dispatch_block_t)block;
|
||||||
|
|
||||||
- (void)initJSEngine;
|
- (void)initJSEngine;
|
||||||
|
|
||||||
|
- (void)teardown;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -101,9 +101,9 @@ - (instancetype)init {
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)teardown {
|
||||||
_destroyed = YES;
|
_destroyed = YES;
|
||||||
};
|
}
|
||||||
|
|
||||||
- (void)ensureRunOnJSThread:(dispatch_block_t)block {
|
- (void)ensureRunOnJSThread:(dispatch_block_t)block {
|
||||||
if (NSThread.currentThread == _jsThread) {
|
if (NSThread.currentThread == _jsThread) {
|
||||||
|
@ -181,4 +181,10 @@ - (void)requestLayout {
|
|||||||
[node requestLayout];
|
[node requestLayout];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)clearSubModel {
|
||||||
|
[super clearSubModel];
|
||||||
|
self.childNodes = @[];
|
||||||
|
self.childViewIds = @[];
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
Reference in New Issue
Block a user