This is an automated email from the ASF dual-hosted git repository.

moshen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-weex.git


The following commit(s) were added to refs/heads/master by this push:
     new ee34a46  [iOS] suuport instance use backup js thread run
     new f2b2e69  Merge pull request #2526 from jianhan-he/master
ee34a46 is described below

commit ee34a4608ad41b7de6474f0b5682bc8733c06fb5
Author: linghe.lh <[email protected]>
AuthorDate: Mon Jun 10 15:48:22 2019 +0800

    [iOS] suuport instance use backup js thread run
---
 ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m   |   4 +-
 ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.mm   |   6 +-
 ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h  |   4 +
 ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m  | 216 ++++++++++++++++-----
 ios/sdk/WeexSDK/Sources/Model/WXComponent.h        |   4 +-
 ios/sdk/WeexSDK/Sources/Model/WXComponent.mm       |   4 +
 ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h      |   5 +
 ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m      |   7 +-
 .../WeexSDK/Sources/Module/WXPrerenderManager.m    |   4 +-
 ios/sdk/WeexSDK/Sources/Monitor/WXAnalyzerCenter.m |   9 +
 ios/sdk/WeexSDK/Sources/Utility/WXAssert.h         |   2 +-
 ios/sdk/WeexSDK/Sources/Utility/WXDefine.h         |   2 +
 12 files changed, 207 insertions(+), 60 deletions(-)

diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m 
b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
index fb8f894..e01f535 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
@@ -754,9 +754,9 @@ _Pragma("clang diagnostic pop") \
         if (_dataRenderHandler) {
             WXPerformBlockOnComponentThread(^{
                 [_dataRenderHandler destroyDataRenderInstance:instance];
-                WXPerformBlockOnBridgeThread(^{
+                WXPerformBlockOnBridgeThreadForInstance(^{
                     [self callJSMethod:@"destroyInstance" args:@[instance]];
-                });
+                }, instance);
             });
         }
         else {
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.mm 
b/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.mm
index a8fb37b..eb34613 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.mm
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.mm
@@ -80,9 +80,9 @@
 {
     _jsContext.instanceId = nil;
     __block JSContext* theContext = _jsContext;
-    WXPerformBlockOnBridgeThread(^{
-        theContext = nil; // release the context in js thread to avoid 
main-thread deadlock
-    });
+    WXPerformBlockOnBridgeThreadForInstance(^{
+         theContext = nil; // release the context in js thread to avoid 
main-thread deadlock
+    }, _weexInstanceId);
 }
 
 - (void)setJSContext:(JSContext *)context
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h 
b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h
index 1cbdad7..80ecee8 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h
@@ -28,6 +28,10 @@ extern "C" {
 #endif
     void WXPerformBlockOnBridgeThread(void (^block)(void));
     void WXPerformBlockSyncOnBridgeThread(void (^block) (void));
+    void WXPerformBlockOnBackupBridgeThread(void (^block)(void));
+
+    void WXPerformBlockOnBridgeThreadForInstance(void (^block)(void), 
NSString* instance);
+    void WXPerformBlockSyncOnBridgeThreadForInstance(void (^block) (void), 
NSString* instance);
 #ifdef __cplusplus
 }
 #endif
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m 
b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
index ef13dab..8283b68 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
@@ -41,11 +41,13 @@
 
 @property (nonatomic, assign) BOOL stopRunning;
 @property (nonatomic, strong) WXBridgeContext *bridgeCtx;
+@property (nonatomic, strong) WXBridgeContext *backupBridgeCtx;
 @property (nonatomic, strong) WXThreadSafeMutableArray *instanceIdStack;
 
 @end
 
 static NSThread *WXBridgeThread;
+static NSThread *WXBackupBridgeThread;
 
 @implementation WXBridgeManager
 
@@ -64,6 +66,7 @@ static NSThread *WXBridgeThread;
     self = [super init];
     if (self) {
         _bridgeCtx = [[WXBridgeContext alloc] init];
+        _backupBridgeCtx = [[WXBridgeContext alloc] init];
     }
     return self;
 }
@@ -76,6 +79,7 @@ static NSThread *WXBridgeThread;
 - (void)unload
 {
     _bridgeCtx = nil;
+    _backupBridgeCtx = nil;
 }
 
 #pragma mark Thread Management
@@ -95,7 +99,6 @@ static NSThread *WXBridgeThread;
 {
     static dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
-        
         WXBridgeThread = [[NSThread alloc] initWithTarget:[[self 
class]sharedManager] selector:@selector(_runLoopThread) object:nil];
         [WXBridgeThread setName:WX_BRIDGE_THREAD_NAME];
         if(WX_SYS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
@@ -110,38 +113,100 @@ static NSThread *WXBridgeThread;
     return WXBridgeThread;
 }
 
++ (NSThread *)backupJsThread
+{
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        WXBackupBridgeThread = [[NSThread alloc] initWithTarget:[[self 
class]sharedManager] selector:@selector(_runLoopThread) object:nil];
+        [WXBackupBridgeThread setName:WX_BACKUP_BRIDGE_THREAD_NAME];
+        if(WX_SYS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
+            [WXBackupBridgeThread setQualityOfService:[[NSThread mainThread] 
qualityOfService]];
+        } else {
+            [WXBackupBridgeThread setThreadPriority:[[NSThread mainThread] 
threadPriority]];
+        }
+
+        [WXBackupBridgeThread start];
+    });
+
+    return WXBackupBridgeThread;
+}
+
+void WXPerformBlockOnBridgeThreadForInstance(void (^block)(void), NSString* 
instance) {
+    [WXBridgeManager _performBlockOnBridgeThread:block instance:instance];
+}
 
 void WXPerformBlockOnBridgeThread(void (^block)(void))
 {
-    [WXBridgeManager _performBlockOnBridgeThread:block];
+    [WXBridgeManager _performBlockOnBridgeThread:block instance:nil];
 }
 
-+ (void)_performBlockOnBridgeThread:(void (^)(void))block
+void WXPerformBlockOnBackupBridgeThread(void (^block)(void))
 {
-    if ([NSThread currentThread] == [self jsThread]) {
+    [WXBridgeManager _performBlockOnBackupBridgeThread:block instance:nil];
+}
+
++ (void)_performBlockOnBackupBridgeThread:(void (^)(void))block 
instance:(NSString*)instanceId
+{
+    if ([NSThread currentThread] == [self backupJsThread]) {
         block();
     } else {
-        [self performSelector:@selector(_performBlockOnBridgeThread:)
-                     onThread:[self jsThread]
+        [self performSelector:@selector(_performBlockOnBridgeThread:instance:)
+                     onThread:[self backupJsThread]
                    withObject:[block copy]
                 waitUntilDone:NO];
     }
 }
 
-void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
++ (void)_performBlockOnBridgeThread:(void (^)(void))block 
instance:(NSString*)instanceId
 {
-    [WXBridgeManager _performBlockSyncOnBridgeThread:block];
+    if ([NSThread currentThread] == [self jsThread] || [NSThread 
currentThread] == [self backupJsThread]) {
+        block();
+    } else {
+        WXSDKInstance* instance = nil;
+        if (instanceId) {
+            instance = [WXSDKManager instanceForID:instanceId];
+        }
+
+        if (instance && instance.useBackupJsThread) {
+            [self 
performSelector:@selector(_performBlockOnBridgeThread:instance:)
+                             onThread:[self backupJsThread]
+                           withObject:[block copy]
+                        waitUntilDone:NO];
+        } else {
+            [self 
performSelector:@selector(_performBlockOnBridgeThread:instance:)
+                             onThread:[self jsThread]
+                           withObject:[block copy]
+                        waitUntilDone:NO];
+        }
+    }
+}
+
+void WXPerformBlockSyncOnBridgeThreadForInstance(void (^block) (void), 
NSString* instance)
+{
+    [WXBridgeManager _performBlockSyncOnBridgeThread:block instance:instance];
 }
 
-+ (void)_performBlockSyncOnBridgeThread:(void (^)(void))block
++ (void)_performBlockSyncOnBridgeThread:(void (^)(void))block 
instance:(NSString*)instanceId
 {
-    if ([NSThread currentThread] == [self jsThread]) {
+    if ([NSThread currentThread] == [self jsThread] || [NSThread 
currentThread] == [self backupJsThread]) {
         block();
     } else {
-        [self performSelector:@selector(_performBlockSyncOnBridgeThread:)
-                     onThread:[self jsThread]
-                   withObject:[block copy]
-                waitUntilDone:YES];
+        WXSDKInstance* instance = nil;
+        if (instanceId) {
+            instance = [WXSDKManager instanceForID:instanceId];
+        }
+
+        if (instance && instance.useBackupJsThread) {
+            [self 
performSelector:@selector(_performBlockOnBridgeThread:instance:)
+                         onThread:[self backupJsThread]
+                       withObject:[block copy]
+                    waitUntilDone:YES];
+        } else {
+            [self 
performSelector:@selector(_performBlockOnBridgeThread:instance:)
+                         onThread:[self jsThread]
+                       withObject:[block copy]
+                    waitUntilDone:YES];
+        }
     }
 }
 
@@ -154,12 +219,17 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) 
(void))
     __weak typeof(self) weakSelf = self;
     NSMutableDictionary *newOptions = [options mutableCopy] ?: 
[NSMutableDictionary new];
     newOptions[@"EXEC_JS"] = @(YES);
-    WXPerformBlockOnBridgeThread(^(){
-        [weakSelf.bridgeCtx createInstance:instance
+    WXPerformBlockOnBridgeThreadForInstance(^(){
+        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instance];
+        if (!sdkInstance) {
+            return;
+        }
+        WXBridgeContext* context = sdkInstance.useBackupJsThread ? 
weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
+        [context createInstance:instance
                                   template:temp
                                    options:newOptions
                                       data:data];
-    });
+    }, instance);
 }
 
 - (void)createInstance:(NSString *)instance
@@ -181,12 +251,13 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) 
(void))
         sdkInstance.apmInstance.isStartRender = YES;
     }
     __weak typeof(self) weakSelf = self;
-    WXPerformBlockOnBridgeThread(^(){
-        [weakSelf.bridgeCtx createInstance:instance
+    WXPerformBlockOnBridgeThreadForInstance(^(){
+        WXBridgeContext* context = sdkInstance.useBackupJsThread ? 
weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
+        [context createInstance:instance
                                   template:temp
                                    options:options
                                       data:data];
-    });
+    }, instance);
 }
 
 - (void)createInstance:(NSString *)instance
@@ -208,12 +279,13 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) 
(void))
         sdkInstance.apmInstance.isStartRender = YES;
     }
     __weak typeof(self) weakSelf = self;
-    WXPerformBlockOnBridgeThread(^(){
-        [weakSelf.bridgeCtx createInstance:instance
+    WXPerformBlockOnBridgeThreadForInstance(^(){
+        WXBridgeContext* context = sdkInstance.useBackupJsThread ? 
weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
+        [context createInstance:instance
                                   contents:contents
                                    options:options
                                       data:data];
-    });
+    }, instance);
 }
 
 - (WXThreadSafeMutableArray *)instanceIdStack
@@ -236,9 +308,11 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
     [self.instanceIdStack removeObject:instance];
     
     __weak typeof(self) weakSelf = self;
-    WXPerformBlockOnBridgeThread(^(){
-        [weakSelf.bridgeCtx destroyInstance:instance];
-    });
+    WXPerformBlockOnBridgeThreadForInstance(^(){
+        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instance];
+        WXBridgeContext* context = sdkInstance.useBackupJsThread ? 
weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
+        [context destroyInstance:instance];
+    }, instance);
 }
 
 - (void)forceGarbageCollection
@@ -255,9 +329,11 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
     if (!instance) return;
     
     __weak typeof(self) weakSelf = self;
-    WXPerformBlockOnBridgeThread(^(){
-        [weakSelf.bridgeCtx refreshInstance:instance data:data];
-    });
+    WXPerformBlockOnBridgeThreadForInstance(^(){
+        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instance];
+        WXBridgeContext* context = sdkInstance.useBackupJsThread ? 
weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
+        [context refreshInstance:instance data:data];
+    }, instance);
 }
 
 - (void)updateState:(NSString *)instance data:(id)data
@@ -265,9 +341,11 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
     if (!instance) return;
     
     __weak typeof(self) weakSelf = self;
-    WXPerformBlockOnBridgeThread(^(){
-        [weakSelf.bridgeCtx updateState:instance data:data];
-    });
+    WXPerformBlockOnBridgeThreadForInstance(^(){
+        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instance];
+        WXBridgeContext* context = sdkInstance && 
sdkInstance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
+        [context updateState:instance data:data];
+    }, instance);
 }
 
 - (void)executeJsFramework:(NSString *)script
@@ -278,26 +356,31 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) 
(void))
     WXPerformBlockOnBridgeThread(^(){
         [weakSelf.bridgeCtx executeJsFramework:script];
     });
+    WXPerformBlockOnBackupBridgeThread(^{
+        [weakSelf.backupBridgeCtx executeJsFramework:script];
+    });
 }
 
 - (void)callJsMethod:(WXCallJSMethod *)method
 {
-    if (!method) return;
+    if (!method || !method.instance) return;
     
     __weak typeof(self) weakSelf = self;
-    WXPerformBlockOnBridgeThread(^(){
-        [weakSelf.bridgeCtx executeJsMethod:method];
-    });
+    WXPerformBlockOnBridgeThreadForInstance(^(){
+        WXBridgeContext* context = method.instance.useBackupJsThread ? 
weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
+        [context executeJsMethod:method];
+    }, method.instance.instanceId);
 }
 
 - (JSValue *)callJSMethodWithResult:(WXCallJSMethod *)method
 {
-    if (!method) return nil;
+    if (!method || !method.instance) return nil;
     __weak typeof(self) weakSelf = self;
     __block JSValue *value;
-    WXPerformBlockSyncOnBridgeThread(^(){
-        value = [weakSelf.bridgeCtx excuteJSMethodWithResult:method];
-    });
+    WXPerformBlockSyncOnBridgeThreadForInstance(^(){
+        WXBridgeContext* context = method.instance.useBackupJsThread ? 
weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
+        value = [context excuteJSMethodWithResult:method];
+    }, method.instance.instanceId);
     return value;
 }
 
@@ -384,6 +467,9 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
             completion(YES);
         }
     });
+    WXPerformBlockOnBackupBridgeThread(^(){
+        [weakSelf.backupBridgeCtx executeJsService:script withName:name];
+    });
 }
 
 - (void)unregisterService:(NSString *)name
@@ -398,6 +484,9 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
         [WXDebugTool removeCacheJsService:name];
         [weakSelf.bridgeCtx executeJsService:script withName:name];
     });
+    WXPerformBlockOnBackupBridgeThread(^(){
+        [weakSelf.backupBridgeCtx executeJsService:script withName:name];
+    });
 }
 
 - (void)registerModules:(NSDictionary *)modules
@@ -408,6 +497,9 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
     WXPerformBlockOnBridgeThread(^(){
         [weakSelf.bridgeCtx registerModules:modules];
     });
+    WXPerformBlockOnBackupBridgeThread(^(){
+        [weakSelf.backupBridgeCtx registerModules:modules];
+    });
 }
 
 - (void)registerComponents:(NSArray *)components
@@ -418,6 +510,9 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
     WXPerformBlockOnBridgeThread(^(){
         [weakSelf.bridgeCtx registerComponents:components];
     });
+    WXPerformBlockOnBackupBridgeThread(^(){
+        [weakSelf.backupBridgeCtx registerComponents:components];
+    });
 }
 
 - (void)fireEvent:(NSString *)instanceId ref:(NSString *)ref type:(NSString 
*)type params:(NSDictionary *)params
@@ -479,7 +574,8 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
 
 - (void)callComponentHook:(NSString*)instanceId 
componentId:(NSString*)componentId type:(NSString*)type 
hook:(NSString*)hookPhase args:(NSArray*)args competion:(void (^)(JSValue * 
value))completion
 {
-    WXPerformBlockOnBridgeThread(^{
+     __weak typeof(self) weakSelf = self;
+    WXPerformBlockOnBridgeThreadForInstance(^{
         if (!type || !instanceId || !hookPhase) {
             WXLogError(@"type and instance id and hookPhase should not be 
nil");
             return;
@@ -487,8 +583,10 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
         NSArray *newArgs = @[componentId, type, hookPhase, args?:@[]];
         
         WXCallJSMethod * method = [[WXCallJSMethod alloc] 
initWithModuleName:nil methodName:@"componentHook" arguments:newArgs 
instance:[WXSDKManager instanceForID:instanceId]];
-        [self.bridgeCtx callJSMethod:@"callJS" args:@[instanceId, 
@[method.callJSTask]] onContext:nil completion:completion];
-    });
+        WXSDKInstance* sdkInstance =  [WXSDKManager instanceForID:instanceId];
+        WXBridgeContext* context = sdkInstance.useBackupJsThread ? 
weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
+        [context callJSMethod:@"callJS" args:@[instanceId, 
@[method.callJSTask]] onContext:nil completion:completion];
+    }, instanceId);
 }
 
 - (JSValue *)fireEventWithResult:(NSString *)instanceId ref:(NSString *)ref 
type:(NSString *)type params:(NSDictionary *)params domChanges:(NSDictionary 
*)domChanges
@@ -542,7 +640,12 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
 }
 
 - (void)connectToDevToolWithUrl:(NSURL *)url {
+    WXPerformBlockOnBridgeThread(^(){
     [self.bridgeCtx connectToDevToolWithUrl:url];
+        });
+    WXPerformBlockOnBackupBridgeThread(^(){
+        [self.backupBridgeCtx connectToDevToolWithUrl:url];
+    });
 }
 
 - (void)connectToWebSocket:(NSURL *)url
@@ -551,6 +654,9 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
     WXPerformBlockOnBridgeThread(^(){
         [weakSelf.bridgeCtx connectToWebSocket:url];
     });
+    WXPerformBlockOnBackupBridgeThread(^(){
+        [weakSelf.backupBridgeCtx connectToWebSocket:url];
+    });
 }
 
 - (void)logToWebSocket:(NSString *)flag message:(NSString *)message
@@ -561,6 +667,9 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
     WXPerformBlockOnBridgeThread(^(){
         [weakSelf.bridgeCtx logToWebSocket:flag message:message];
     });
+    WXPerformBlockOnBackupBridgeThread(^(){
+        [weakSelf.backupBridgeCtx logToWebSocket:flag message:message];
+    });
 }
 
 - (void)resetEnvironment
@@ -569,6 +678,9 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) (void))
     WXPerformBlockOnBridgeThread(^(){
         [weakSelf.bridgeCtx resetEnvironment];
     });
+    WXPerformBlockOnBackupBridgeThread(^(){
+        [weakSelf.backupBridgeCtx resetEnvironment];
+    });
 }
 
 - (void)callJSMethod:(NSString *)method args:(NSArray *)args
@@ -576,21 +688,25 @@ void WXPerformBlockSyncOnBridgeThread(void (^block) 
(void))
     if (!method) return;
 
     __weak typeof(self) weakSelf = self;
-    WXPerformBlockOnBridgeThread(^(){
-        [weakSelf.bridgeCtx callJSMethod:method args:args onContext:nil 
completion:nil];
-    });
+    NSString* instanceId = args[0];
+    WXPerformBlockOnBridgeThreadForInstance(^(){
+        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instanceId];
+        WXBridgeContext* context = sdkInstance && 
sdkInstance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
+        [context callJSMethod:method args:args onContext:nil completion:nil];
+    }, instanceId);
 }
 
 #pragma mark - Deprecated
 
 - (void)executeJsMethod:(WXCallJSMethod *)method
 {
-    if (!method) return;
+    if (!method || !method.instance) return;
     
     __weak typeof(self) weakSelf = self;
-    WXPerformBlockOnBridgeThread(^(){
-        [weakSelf.bridgeCtx executeJsMethod:method];
-    });
+    WXPerformBlockOnBridgeThreadForInstance(^(){
+        WXBridgeContext* context = method.instance.useBackupJsThread ? 
weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
+        [context executeJsMethod:method];
+    }, method.instance.instanceId);
 }
 
 @end
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.h 
b/ios/sdk/WeexSDK/Sources/Model/WXComponent.h
index f645c63..cd0f117 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.h
+++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.h
@@ -28,7 +28,8 @@ typedef enum : NSUInteger {
 } WXDisplayType;
 
 typedef enum : NSUInteger {
-    WXComponentViewCreatedCallback
+    WXComponentViewCreatedCallback,
+    WXComponentUpdateStylesCallback
 } WXComponentCallbackType;
 
 /**
@@ -177,6 +178,7 @@ NS_ASSUME_NONNULL_BEGIN
  *  The callback of the component
  *
  *  When the callbackType is WXComponentViewCreatedCallback, the result type 
is UIView.
+ *  When the callbackType is WXComponentUpdateStylesCallback, the result type 
is NSDictionary.
  *
  *  @return A block that takes component, callbackType and a result.
  **/
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm 
b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
index 44e69c5..13720b9 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
+++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
@@ -800,6 +800,10 @@ static BOOL bNeedRemoveEvents = YES;
 - (void)updateStyles:(NSDictionary *)styles
 {
     WXAssertMainThread();
+
+    if (self.componentCallback) {
+        self.componentCallback(self, WXComponentUpdateStylesCallback, styles);
+    }
 }
 
 - (void)updateAttributes:(NSDictionary *)attributes
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h 
b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
index e076212..de98c9c 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
+++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
@@ -52,6 +52,11 @@ extern NSString *const bundleUrlOptionKey;
 @property (nonatomic, assign) BOOL needValidate;
 
 /**
+ * Which indicates current instance use backup JS thread run,default value is 
false.
+ **/
+@property (nonatomic, assign) BOOL useBackupJsThread;
+
+/**
  * The scriptURL of weex bundle.
  **/
 @property (nonatomic, strong) NSURL *scriptURL;
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m 
b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
index ba052fe..65f376f 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
+++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
@@ -119,6 +119,8 @@ typedef enum : NSUInteger {
         
         _defaultDataRender = NO;
         
+        _useBackupJsThread = NO;
+
         [self addObservers];
     }
     return self;
@@ -143,6 +145,9 @@ typedef enum : NSUInteger {
     _instanceJavaScriptContext = _debugJS ? [NSClassFromString(@"WXDebugger") 
alloc] : [[WXJSCoreBridge alloc] initWithoutDefaultContext];
     if (!_debugJS) {
         id<WXBridgeProtocol> jsBridge = [[WXSDKManager bridgeMgr] 
valueForKeyPath:@"bridgeCtx.jsBridge"];
+        if (_useBackupJsThread) {
+              jsBridge = [[WXSDKManager bridgeMgr] 
valueForKeyPath:@"backupBridgeCtx.jsBridge"];
+        }
         JSContext* globalContex = jsBridge.javaScriptContext;
         JSContextGroupRef contextGroup = JSContextGetGroup([globalContex 
JSGlobalContextRef]);
         JSClassDefinition classDefinition = kJSClassDefinitionEmpty;
@@ -568,7 +573,7 @@ typedef enum : NSUInteger {
         if (strongSelf == nil) {
             return;
         }
-        
+
         NSMutableDictionary* optionsCopy = [strongSelf->_options mutableCopy];
         optionsCopy[bundleResponseUrlOptionKey] = [response.URL 
absoluteString];
         strongSelf->_options = [optionsCopy copy];
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXPrerenderManager.m 
b/ios/sdk/WeexSDK/Sources/Module/WXPrerenderManager.m
index 822b5ce..a85518c 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXPrerenderManager.m
+++ b/ios/sdk/WeexSDK/Sources/Module/WXPrerenderManager.m
@@ -299,9 +299,9 @@ static NSString *const MSG_PRERENDER_SUCCESS = @"success";
             [task.instance.componentManager executePrerenderUITask:url];
             task.instance.needPrerender = NO;
         });
-        WXPerformBlockOnBridgeThread(^(){
+        WXPerformBlockOnBridgeThreadForInstance(^{
             [WXPrerenderManager excuteModuleTasksForUrl:url];
-        });
+        }, task.instance.instanceId);
     }
 }
 
diff --git a/ios/sdk/WeexSDK/Sources/Monitor/WXAnalyzerCenter.m 
b/ios/sdk/WeexSDK/Sources/Monitor/WXAnalyzerCenter.m
index eac8fac..dff871c 100644
--- a/ios/sdk/WeexSDK/Sources/Monitor/WXAnalyzerCenter.m
+++ b/ios/sdk/WeexSDK/Sources/Monitor/WXAnalyzerCenter.m
@@ -209,6 +209,15 @@
             });
         }
     }
+    if ([WXSDKManager.bridgeMgr 
respondsToSelector:@selector(backupBridgeCtx)]) {
+        id backupBridgeCtx = [WXSDKManager.bridgeMgr 
performSelector:@selector(backupBridgeCtx) withObject:nil];
+        if (nil != backupBridgeCtx && [backupBridgeCtx 
respondsToSelector:@selector(callJSMethod:args:)]) {
+            WXPerformBlockOnBackupBridgeThread(^(){
+                NSArray* args = @[isOpen?@(1):@(0)];
+                [backupBridgeCtx performSelector:@selector(callJSMethod:args:) 
withObject:@"switchInteractionLog" withObject:args];
+            });
+        }
+    }
 #pragma clang diagnostic pop
 }
 
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXAssert.h 
b/ios/sdk/WeexSDK/Sources/Utility/WXAssert.h
index 7937c4b..f856ec8 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXAssert.h
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXAssert.h
@@ -70,7 +70,7 @@ WXAssert([[NSThread currentThread].name 
isEqualToString:WX_COMPONENT_THREAD_NAME
  *  @abstract macro for asserting that we are running on the bridge thread.
  */
 #define WXAssertBridgeThread() \
-WXAssert([[NSThread currentThread].name 
isEqualToString:WX_BRIDGE_THREAD_NAME], \
+WXAssert([[NSThread currentThread].name isEqualToString:WX_BRIDGE_THREAD_NAME] 
|| [[NSThread currentThread].name 
isEqualToString:WX_BACKUP_BRIDGE_THREAD_NAME], \
 @"must be called on the bridge thread")
 
 #define WXAssertNotReached() \
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXDefine.h 
b/ios/sdk/WeexSDK/Sources/Utility/WXDefine.h
index 2520ccb..3ade6e2 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXDefine.h
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXDefine.h
@@ -89,6 +89,8 @@ parts = [parts subarrayWithRange:(NSRange){0, parts.count - 
1}];\
 
 #define WX_BRIDGE_THREAD_NAME @"com.taobao.weex.bridge"
 
+#define WX_BACKUP_BRIDGE_THREAD_NAME @"com.taobao.weex.backup.bridge"
+
 #define WX_FONT_DOWNLOAD_DIR [[WXUtility cacheDirectory] 
stringByAppendingPathComponent:[NSString stringWithFormat:@"wxdownload"]]
 
 #define WX_EXPORT_METHOD_INTERNAL(method, token) \

Reply via email to