You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by cx...@apache.org on 2018/06/20 11:03:06 UTC

incubator-weex git commit: [WEEX-467][iOS] Fix multithread issues related to transition animation.

Repository: incubator-weex
Updated Branches:
  refs/heads/master 216684c05 -> 35e61d9b5


[WEEX-467][iOS] Fix multithread issues related to transition animation.


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/35e61d9b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/35e61d9b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/35e61d9b

Branch: refs/heads/master
Commit: 35e61d9b5f1e2efebbbc7e42d5d4753e9691e6b3
Parents: 216684c
Author: 神漠 <qi...@alipay.com>
Authored: Wed Jun 20 18:10:37 2018 +0800
Committer: Adam Feng <cx...@gmail.com>
Committed: Wed Jun 20 19:03:05 2018 +0800

----------------------------------------------------------------------
 ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h   | 5 +++++
 ios/sdk/WeexSDK/Sources/Model/WXComponent.mm               | 4 +++-
 ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m         | 2 +-
 ios/sdk/WeexSDK/Sources/Module/WXTransition.mm             | 9 +++++++--
 ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.mm | 5 +++--
 5 files changed, 19 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/35e61d9b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
index 5f63065..d8e2f84 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
+++ b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
@@ -152,6 +152,11 @@ typedef id (^WXDataBindingBlock)(NSDictionary *data, BOOL *needUpdate);
     NSMutableDictionary<NSString *, NSArray *> *_eventParameters;
 }
 
+/* _transform may be modified in mutiple threads. DO NOT use "_transform = XXX" directly.
+ Ivar access in ObjC is compiled to code with additional release or retain. So use Ivar in mutiple
+ thread may lead to crash. Use an ATOMIC property is well enough. */
+@property (atomic, strong) WXTransform *transform;
+
 ///--------------------------------------
 /// @name Package Internal Methods
 ///--------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/35e61d9b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
index 58df862..d877868 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
+++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
@@ -69,6 +69,8 @@ static BOOL bNeedRemoveEvents = YES;
     __weak WXSDKInstance *_weexInstance;
 }
 
+@synthesize transform = _transform;
+
 #pragma mark Life Cycle
 
 - (instancetype)initWithRef:(NSString *)ref
@@ -758,7 +760,7 @@ static BOOL bNeedRemoveEvents = YES;
 {
     WXAssertMainThread();
     
-    _transform = [[WXTransform alloc] initWithNativeTransform:CATransform3DMakeAffineTransform(transform) instance:self.weexInstance];
+    self.transform = [[WXTransform alloc] initWithNativeTransform:CATransform3DMakeAffineTransform(transform) instance:self.weexInstance];
     if (!CGRectEqualToRect(self.calculatedFrame, CGRectZero)) {
         [_transform applyTransformForView:_view];
         [_layer setNeedsDisplay];

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/35e61d9b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
index c8afd2b..6ed9441 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
+++ b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
@@ -264,7 +264,7 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:))
                 newInfo.toValue = @([wxTransform.translateY valueForMaximum:view.bounds.size.height]);
                 [infos addObject:newInfo];
             }
-            target->_transform = wxTransform;
+            target.transform = wxTransform;
         } else if ([property isEqualToString:@"backgroundColor"]) {
             info.propertyName = @"backgroundColor";
             info.fromValue = (__bridge id)(layer.backgroundColor);

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/35e61d9b/ios/sdk/WeexSDK/Sources/Module/WXTransition.mm
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXTransition.mm b/ios/sdk/WeexSDK/Sources/Module/WXTransition.mm
index 8e982ac..d185981 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXTransition.mm
+++ b/ios/sdk/WeexSDK/Sources/Module/WXTransition.mm
@@ -256,7 +256,7 @@
                 info.perValue = @([wxTransform.translateY floatValue] - [oldTransform.translateY floatValue]);
                 [_propertyArray addObject:info];
             }
-            _targetComponent->_transform = wxTransform;
+            _targetComponent.transform = wxTransform;
         }
         else
         {
@@ -355,8 +355,13 @@
             [_oldFilterStyles setObject:@(currentValue) forKey:info.propertyName];
         }
     }
+    
+    /* _oldFilterStyles could be modified in current thread while _updateViewStyles uses it in main thread.
+     This may lead to crash in _updateViewStyles because the dictionary items may be retained or
+     released multiple times by code like styles[@"transform"]. So we copy _oldFilterStyles and use a duplicate.*/
+    NSDictionary* dupStyles = [NSDictionary dictionaryWithDictionary:_oldFilterStyles];
     WXPerformBlockOnMainThread(^{
-        [_targetComponent _updateViewStyles:_oldFilterStyles];
+        [_targetComponent _updateViewStyles:dupStyles];
     });
     [_targetComponent _updateCSSNodeStyles:_oldFilterStyles];
     [_targetComponent.weexInstance.componentManager startComponentTasks];

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/35e61d9b/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.mm
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.mm b/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.mm
index 740e168..1fccb5c 100644
--- a/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.mm
+++ b/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.mm
@@ -252,11 +252,12 @@ do {\
     }
     if (styles[@"transform"]) {
         id transformOrigin = styles[@"transformOrigin"] ?: self.styles[@"transformOrigin"];
-        _transform = [[WXTransform alloc] initWithCSSValue:[WXConvert NSString:styles[@"transform"]] origin:[WXConvert NSString:transformOrigin] instance:self.weexInstance];
+        WXTransform* transform = [[WXTransform alloc] initWithCSSValue:[WXConvert NSString:styles[@"transform"]] origin:[WXConvert NSString:transformOrigin] instance:self.weexInstance];
         if (!CGRectEqualToRect(self.calculatedFrame, CGRectZero)) {
-            [_transform applyTransformForView:_view];
+            [transform applyTransformForView:_view];
             [_layer setNeedsDisplay];
         }
+        self.transform = transform;
     }else if (styles[@"transformOrigin"]) {
         [_transform setTransformOrigin:[WXConvert NSString:styles[@"transformOrigin"]]];
         if (!CGRectEqualToRect(self.calculatedFrame, CGRectZero)) {