Skip to content
This repository has been archived by the owner on Jun 3, 2021. It is now read-only.

Commit

Permalink
[iOS] fix multi jsthread error
Browse files Browse the repository at this point in the history
  • Loading branch information
jianhan-he committed Aug 1, 2019
1 parent 76bfd6b commit e4c48f5
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 22 deletions.
2 changes: 2 additions & 0 deletions ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h
Expand Up @@ -242,4 +242,6 @@ extern "C" {

- (void)callJSMethod:(NSString *)method args:(NSArray *)args;

- (void)executeJSTaskQueue;

@end
124 changes: 102 additions & 22 deletions ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
Expand Up @@ -41,9 +41,11 @@
@interface WXBridgeManager ()

@property (nonatomic, assign) BOOL stopRunning;
@property (nonatomic, assign) BOOL supportMultiJSThread;
@property (nonatomic, strong) WXBridgeContext *bridgeCtx;
@property (nonatomic, strong) WXBridgeContext *backupBridgeCtx;
@property (nonatomic, strong) WXThreadSafeMutableArray *instanceIdStack;
@property (nonatomic, strong) NSMutableArray* jsTaskQueue;

@end

Expand All @@ -67,11 +69,24 @@ - (instancetype)init
self = [super init];
if (self) {
_bridgeCtx = [[WXBridgeContext alloc] init];
_backupBridgeCtx = [[WXBridgeContext alloc] init];
_supportMultiJSThread = YES;
_jsTaskQueue = [NSMutableArray array];
}
return self;
}

- (WXBridgeContext *)backupBridgeCtx {
if (_backupBridgeCtx) {
return _backupBridgeCtx;
}
if (!_supportMultiJSThread) {
_backupBridgeCtx = _bridgeCtx;
} else {
_backupBridgeCtx = [[WXBridgeContext alloc] init];
}
return _backupBridgeCtx;
}

- (WXSDKInstance *)topInstance
{
return _bridgeCtx.topInstance;
Expand Down Expand Up @@ -122,34 +137,41 @@ + (NSThread *)backupJsThread
return WXBackupBridgeThread;
}

void WXPerformBlockOnBridgeThreadForInstance(void (^block)(void), NSString* instance) {
[WXBridgeManager _performBlockOnBridgeThread:block instance:instance];
}

void WXPerformBlockOnBridgeThread(void (^block)(void))
{
[WXBridgeManager _performBlockOnBridgeThread:block instance:nil];
[WXBridgeManager _performBlockOnBridgeThread:block];
}

void WXPerformBlockOnBackupBridgeThread(void (^block)(void))
{
[WXBridgeManager _performBlockOnBackupBridgeThread:block instance:nil];
void WXPerformBlockOnBridgeThreadForInstance(void (^block)(void), NSString* instance) {
[WXBridgeManager _performBlockOnBridgeThread:block instance:instance];
}

+ (void)_performBlockOnBackupBridgeThread:(void (^)(void))block instance:(NSString*)instanceId
+ (void)_performBlockOnBridgeThread:(void (^)(void))block
{
if ([NSThread currentThread] == [self backupJsThread]) {
if ([NSThread currentThread] == [self jsThread]) {
block();
} else {
[self performSelector:@selector(_performBlockOnBridgeThread:instance:)
onThread:[self backupJsThread]
withObject:[block copy]
waitUntilDone:NO];
onThread:[self jsThread]
withObject:[block copy]
waitUntilDone:NO];
}
}

+ (void)_performBlockOnBridgeThread:(void (^)(void))block instance:(NSString*)instanceId
{
if (![WXSDKManager bridgeMgr].supportMultiJSThread) {
if ([NSThread currentThread] == [self jsThread]) {
block();
} else {
[self performSelector:@selector(_performBlockOnBridgeThread:instance:)
onThread:[self jsThread]
withObject:[block copy]
waitUntilDone:NO];
}
return;
}

if ([NSThread currentThread] == [self jsThread] || [NSThread currentThread] == [self backupJsThread]) {
block();
} else {
Expand All @@ -160,25 +182,73 @@ + (void)_performBlockOnBridgeThread:(void (^)(void))block instance:(NSString*)in

if (instance && instance.useBackupJsThread) {
[self performSelector:@selector(_performBlockOnBridgeThread:instance:)
onThread:[self backupJsThread]
withObject:[block copy]
waitUntilDone:NO];
onThread:[self backupJsThread]
withObject:[block copy]
waitUntilDone:NO];
} else {
[self performSelector:@selector(_performBlockOnBridgeThread:instance:)
onThread:[self jsThread]
withObject:[block copy]
waitUntilDone:NO];
onThread:[self jsThread]
withObject:[block copy]
waitUntilDone:NO];
}
}
}

void WXPerformBlockOnBackupBridgeThread(void (^block)(void))
{
[WXBridgeManager _performBlockOnBackupBridgeThread:block putInTaskQueue:YES];
}

+ (void)_performBlockOnBackupBridgeThread:(void (^)(void))block putInTaskQueue:(BOOL)putInTaskQueue
{
if (![WXSDKManager bridgeMgr].supportMultiJSThread) {
return;
}
if (putInTaskQueue) {
[[WXSDKManager bridgeMgr].jsTaskQueue addObject:block];
} else {
[self performSelector:@selector(_performBlockOnBridgeThread:instance:)
onThread:[self backupJsThread]
withObject:[block copy]
waitUntilDone:NO];
}
}

void WXPerformBlockSyncOnBridgeThread(void (^block) (void)) {
[WXBridgeManager _performBlockSyncOnBridgeThread:block];
}

void WXPerformBlockSyncOnBridgeThreadForInstance(void (^block) (void), NSString* instance)
{
[WXBridgeManager _performBlockSyncOnBridgeThread:block instance:instance];
}

+ (void)_performBlockSyncOnBridgeThread:(void (^)(void))block
{
if ([NSThread currentThread] == [self jsThread]) {
block();
} else {
[self performSelector:@selector(_performBlockSyncOnBridgeThread:)
onThread:[self jsThread]
withObject:[block copy]
waitUntilDone:YES];
}
}

+ (void)_performBlockSyncOnBridgeThread:(void (^)(void))block instance:(NSString*)instanceId
{
if (![WXSDKManager bridgeMgr].supportMultiJSThread) {
if ([NSThread currentThread] == [self jsThread]) {
block();
} else {
[self performSelector:@selector(_performBlockSyncOnBridgeThread:instance:)
onThread:[self jsThread]
withObject:[block copy]
waitUntilDone:YES];
}
return;
}

if ([NSThread currentThread] == [self jsThread] || [NSThread currentThread] == [self backupJsThread]) {
block();
} else {
Expand All @@ -188,12 +258,12 @@ + (void)_performBlockSyncOnBridgeThread:(void (^)(void))block instance:(NSString
}

if (instance && instance.useBackupJsThread) {
[self performSelector:@selector(_performBlockOnBridgeThread:instance:)
[self performSelector:@selector(_performBlockSyncOnBridgeThread:instance:)
onThread:[self backupJsThread]
withObject:[block copy]
waitUntilDone:YES];
} else {
[self performSelector:@selector(_performBlockOnBridgeThread:instance:)
[self performSelector:@selector(_performBlockSyncOnBridgeThread:instance:)
onThread:[self jsThread]
withObject:[block copy]
waitUntilDone:YES];
Expand Down Expand Up @@ -279,6 +349,16 @@ - (void)createInstance:(NSString *)instance
}, instance);
}

- (void)executeJSTaskQueue {
if (_jsTaskQueue.count == 0 || !_supportMultiJSThread) {
return;
}
for (id block in _jsTaskQueue) {
[WXBridgeManager _performBlockOnBackupBridgeThread:block putInTaskQueue:NO];
}
[_jsTaskQueue removeAllObjects];
}

- (WXThreadSafeMutableArray *)instanceIdStack
{
if (_instanceIdStack) return _instanceIdStack;
Expand Down
6 changes: 6 additions & 0 deletions ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
Expand Up @@ -308,6 +308,9 @@ - (void)renderWithURL:(NSURL *)url options:(NSDictionary *)options data:(id)data
return;
}
[WXCoreBridge install];
if (_useBackupJsThread) {
[[WXSDKManager bridgeMgr] executeJSTaskQueue];
}

self.scriptURL = url;
[self _checkPageName];
Expand All @@ -327,6 +330,9 @@ - (void)renderView:(id)source options:(NSDictionary *)options data:(id)data
_options = [options isKindOfClass:[NSDictionary class]] ? options : nil;
_jsData = data;
[WXCoreBridge install];
if (_useBackupJsThread) {
[[WXSDKManager bridgeMgr] executeJSTaskQueue];
}

self.needValidate = [[WXHandlerFactory handlerForProtocol:@protocol(WXValidateProtocol)] needValidate:self.scriptURL];

Expand Down

0 comments on commit e4c48f5

Please sign in to comment.