You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ac...@apache.org on 2018/04/26 12:39:55 UTC

[03/16] incubator-weex git commit: [WEEX-311] [iOS] use new layoutEngin to replace yoga

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b77b4259/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm
new file mode 100644
index 0000000..c8c6e3f
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm
@@ -0,0 +1,1158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import "WXComponentManager.h"
+#import "WXComponent.h"
+#import "WXComponent_internal.h"
+#import "WXComponent+DataBinding.h"
+#import "WXComponentFactory.h"
+#import "WXDefine.h"
+#import "NSArray+Weex.h"
+#import "WXSDKInstance.h"
+#import "WXAssert.h"
+#import "WXUtility.h"
+#import "WXMonitor.h"
+#import "WXScrollerProtocol.h"
+#import "WXSDKManager.h"
+#import "WXSDKError.h"
+#import "WXInvocationConfig.h"
+#import "WXHandlerFactory.h"
+#import "WXValidateProtocol.h"
+#import "WXPrerenderManager.h"
+#import "WXTracingManager.h"
+#import "WXLayoutDefine.h"
+#import "WXSDKInstance_performance.h"
+#import "WXRootView.h"
+#import "WXComponent+Layout.h"
+
+
+
+static NSThread *WXComponentThread;
+
+#define WXAssertComponentExist(component)  WXAssert(component, @"component not exists")
+
+
+@implementation WXComponentManager
+{
+    __weak WXSDKInstance *_weexInstance;
+    BOOL _isValid;
+    
+    BOOL _stopRunning;
+    NSUInteger _noTaskTickCount;
+    
+    // access only on component thread
+    NSMapTable<NSString *, WXComponent *> *_indexDict;
+    NSMutableArray<dispatch_block_t> *_uiTaskQueue;
+    NSMutableDictionary *_uiPrerenderTaskQueue;
+
+    WXComponent *_rootComponent;
+    NSMutableArray *_fixedComponents;
+//#ifndef USE_FLEX
+    css_node_t *_rootCSSNode;
+//#else
+    WeexCore::WXCoreLayoutNode* _rootFlexCSSNode;
+//#endif
+    CADisplayLink *_displayLink;
+}
+
++ (instancetype)sharedManager
+{
+    static id _sharedInstance = nil;
+    static dispatch_once_t oncePredicate;
+    dispatch_once(&oncePredicate, ^{
+        _sharedInstance = [[self alloc] init];
+    });
+    return _sharedInstance;
+}
+
+- (instancetype)initWithWeexInstance:(id)weexInstance
+{
+    if (self = [self init]) {
+        _weexInstance = weexInstance;
+        
+        _indexDict = [NSMapTable strongToWeakObjectsMapTable];
+        _fixedComponents = [NSMutableArray wx_mutableArrayUsingWeakReferences];
+        _uiTaskQueue = [NSMutableArray array];
+        _isValid = YES;
+        [self _startDisplayLink];
+    }
+    
+    return self;
+}
+
+- (void)dealloc
+{
+//#ifndef USE_FLEX
+    if(![WXComponent isUseFlex])
+    {
+         free_css_node(_rootCSSNode);
+    }
+   
+//#else
+    
+    if(_rootFlexCSSNode){
+        delete _rootFlexCSSNode;
+        
+       // WeexCore::WXCoreLayoutNode::freeNodeTree(_rootFlexCSSNode);
+        _rootFlexCSSNode=nullptr;
+    }
+//#endif
+    [NSMutableArray wx_releaseArray:_fixedComponents];
+}
+
+#pragma mark Thread Management
+
++ (NSThread *)componentThread
+{
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        WXComponentThread = [[NSThread alloc] initWithTarget:[self sharedManager] selector:@selector(_runLoopThread) object:nil];
+        [WXComponentThread setName:WX_COMPONENT_THREAD_NAME];
+        if(WX_SYS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
+            [WXComponentThread setQualityOfService:[[NSThread mainThread] qualityOfService]];
+        } else {
+            [WXComponentThread setThreadPriority:[[NSThread mainThread] threadPriority]];
+        }
+        
+        [WXComponentThread start];
+    });
+    
+    return WXComponentThread;
+}
+
+- (void)_runLoopThread
+{
+    [[NSRunLoop currentRunLoop] addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
+    
+    while (!_stopRunning) {
+        @autoreleasepool {
+            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
+        }
+    }
+}
+
++ (void)_performBlockOnComponentThread:(void (^)(void))block
+{
+    if([NSThread currentThread] == [self componentThread]){
+        block();
+    } else {
+        [self performSelector:@selector(_performBlockOnComponentThread:)
+                     onThread:WXComponentThread
+                   withObject:[block copy]
+                waitUntilDone:NO];
+    }
+}
+
++ (void)_performBlockSyncOnComponentThread:(void (^)(void))block
+{
+    if([NSThread currentThread] == [self componentThread]){
+        block();
+    } else {
+        [self performSelector:@selector(_performBlockOnComponentThread:)
+                     onThread:WXComponentThread
+                   withObject:[block copy]
+                waitUntilDone:YES];
+    }
+}
+
+- (void)startComponentTasks
+{
+    [self _awakeDisplayLink];
+}
+
+- (void)rootViewFrameDidChange:(CGRect)frame
+{
+    WXAssertComponentThread();
+//#ifndef USE_FLEX
+    
+    if (![WXComponent isUseFlex]) {
+        if (_rootCSSNode) {
+            [self _applyRootFrame:frame toRootCSSNode:_rootCSSNode];
+            if (!_rootComponent.styles[@"width"]) {
+                _rootComponent.cssNode->style.dimensions[CSS_WIDTH] = frame.size.width ?: CSS_UNDEFINED;
+            }
+            if (!_rootComponent.styles[@"height"]) {
+                _rootComponent.cssNode->style.dimensions[CSS_HEIGHT] = frame.size.height ?: CSS_UNDEFINED;
+            }
+        }
+    }
+//#else
+    else
+    {
+        if (_rootFlexCSSNode) {
+            [self _applyRootFrame:frame];
+            if (!_rootComponent.styles[@"width"]) {
+                _rootComponent.flexCssNode->setStyleWidth(frame.size.width ?:FlexUndefined,NO);
+            }
+            if (!_rootComponent.styles[@"height"]) {
+                _rootComponent.flexCssNode->setStyleHeight(frame.size.height ?:FlexUndefined);
+            }
+        }
+    }
+//#endif
+    [_rootComponent setNeedsLayout];
+    [self startComponentTasks];
+}
+
+//#ifndef USE_FLEX
+- (void)_applyRootFrame:(CGRect)rootFrame toRootCSSNode:(css_node_t *)rootCSSNode
+{
+    _rootCSSNode->style.position[CSS_LEFT] = self.weexInstance.frame.origin.x;
+    _rootCSSNode->style.position[CSS_TOP] = self.weexInstance.frame.origin.y;
+    // if no instance width/height, use layout width/height, as Android's wrap_content
+    _rootCSSNode->style.dimensions[CSS_WIDTH] = self.weexInstance.frame.size.width ?: CSS_UNDEFINED;
+    _rootCSSNode->style.dimensions[CSS_HEIGHT] =  self.weexInstance.frame.size.height ?: CSS_UNDEFINED;
+}
+//#else
+- (void)_applyRootFrame:(CGRect)rootFrame{
+    _rootFlexCSSNode->setStylePosition(WeexCore::kPositionEdgeLeft, self.weexInstance.frame.origin.x);
+    _rootFlexCSSNode->setStylePosition(WeexCore::kPositionEdgeTop, self.weexInstance.frame.origin.y);
+    _rootFlexCSSNode->setStyleWidth(self.weexInstance.frame.size.width ?: FlexUndefined,NO);
+    _rootFlexCSSNode->setStyleHeight(self.weexInstance.frame.size.height ?: FlexUndefined);
+}
+//#endif
+
+- (void)_addUITask:(void (^)(void))block
+{
+    if(!_uiPrerenderTaskQueue){
+        _uiPrerenderTaskQueue = [NSMutableDictionary new];
+    }
+    if(self.weexInstance.needPrerender){
+        NSMutableArray<dispatch_block_t> *tasks  = [_uiPrerenderTaskQueue objectForKey:[WXPrerenderManager getTaskKeyFromUrl:self.weexInstance.scriptURL.absoluteString]];
+        if(!tasks){
+            tasks = [NSMutableArray new];
+        }
+        [tasks addObject:block];
+        [_uiPrerenderTaskQueue setObject:tasks forKey:[WXPrerenderManager getTaskKeyFromUrl:self.weexInstance.scriptURL.absoluteString]];
+    }else{
+        [_uiTaskQueue addObject:block];
+    }
+}
+
+- (void)excutePrerenderUITask:(NSString *)url
+{
+    NSMutableArray *tasks  = [_uiPrerenderTaskQueue objectForKey:[WXPrerenderManager getTaskKeyFromUrl:self.weexInstance.scriptURL.absoluteString]];
+    for (id block in tasks) {
+        [_uiTaskQueue addObject:block];
+    }
+    tasks = [NSMutableArray new];
+    [_uiPrerenderTaskQueue setObject:tasks forKey:[WXPrerenderManager getTaskKeyFromUrl:self.weexInstance.scriptURL.absoluteString]];
+}
+
+#pragma mark Component Tree Building
+
+- (void)createRoot:(NSDictionary *)data
+{
+    WXAssertComponentThread();
+    WXAssertParam(data);
+    
+    _rootComponent = [self _buildComponentForData:data supercomponent:nil];
+//#ifndef USE_FLEX
+    if(![WXComponent isUseFlex])
+    {
+        [self _initRootCSSNode];
+    }
+//#else
+    else
+    {
+        [self _initRootFlexCssNode];
+        _rootFlexCSSNode->addChildAt(_rootComponent.flexCssNode, (uint32_t)[_fixedComponents count]);
+    }
+//#endif
+    
+    NSArray *subcomponentsData = [data valueForKey:@"children"];
+    if (subcomponentsData) {
+        BOOL appendTree = [_rootComponent.attributes[@"append"] isEqualToString:@"tree"];
+        for(NSDictionary *subcomponentData in subcomponentsData){
+            [self _recursivelyAddComponent:subcomponentData toSupercomponent:_rootComponent atIndex:-1 appendingInTree:appendTree];
+        }
+    }
+    
+    __weak typeof(self) weakSelf = self;
+    WX_MONITOR_INSTANCE_PERF_END(WXFirstScreenJSFExecuteTime, self.weexInstance);
+    [self _addUITask:^{
+        [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:data[@"ref"] className:nil name:data[@"type"] phase:WXTracingBegin functionName:@"createBody" options:@{@"threadName":WXTUIThread}];
+        __strong typeof(self) strongSelf = weakSelf;
+        strongSelf.weexInstance.rootView.wx_component = strongSelf->_rootComponent;
+        [strongSelf.weexInstance.rootView addSubview:strongSelf->_rootComponent.view];
+        [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:data[@"ref"] className:nil name:data[@"type"] phase:WXTracingEnd functionName:@"createBody" options:@{@"threadName":WXTUIThread}];
+    }];
+    
+    
+}
+
+//#ifndef USE_FLEX
+static bool rootNodeIsDirty(void *context)
+{
+    WXComponentManager *manager = (__bridge WXComponentManager *)(context);
+    return [manager->_rootComponent needsLayout];
+}
+
+static css_node_t * rootNodeGetChild(void *context, int i)
+{
+    WXComponentManager *manager = (__bridge WXComponentManager *)(context);
+    if (i == 0) {
+        return manager->_rootComponent.cssNode;
+    } else if(manager->_fixedComponents.count >= i) {
+        return ((WXComponent *)((manager->_fixedComponents)[i-1])).cssNode;
+    }
+    
+    return NULL;
+}
+//#endif
+
+- (void)addComponent:(NSDictionary *)componentData toSupercomponent:(NSString *)superRef atIndex:(NSInteger)index appendingInTree:(BOOL)appendingInTree
+{
+    WXAssertComponentThread();
+    WXAssertParam(componentData);
+    WXAssertParam(superRef);
+    
+    WXComponent *supercomponent = [_indexDict objectForKey:superRef];
+    WXAssertComponentExist(supercomponent);
+    
+    if ([WXComponent isUseFlex] && !supercomponent) {
+        WXLogWarning(@"addComponent,superRef from js never exit ! check JS action, supRef:%@",superRef);
+        return;
+    }
+    
+    [self _recursivelyAddComponent:componentData toSupercomponent:supercomponent atIndex:index appendingInTree:appendingInTree];
+}
+
+- (void)_recursivelyAddComponent:(NSDictionary *)componentData toSupercomponent:(WXComponent *)supercomponent atIndex:(NSInteger)index appendingInTree:(BOOL)appendingInTree
+{
+    WXComponent *component = [self _buildComponentForData:componentData supercomponent:supercomponent];
+    if (!supercomponent.subcomponents) {
+        index = 0;
+    } else {
+        index = (index == -1 ? supercomponent->_subcomponents.count : index);
+    }
+    
+#ifdef DEBUG
+//#ifndef USE_FLEX
+    if(![WXComponent isUseFlex])
+    {
+        WXLogDebug(@"flexLayout -> _recursivelyAddComponent : super:(%@,%@):[%f,%f] ,child:(%@,%@):[%f,%f],childClass:%@",
+              supercomponent.type,
+              supercomponent.ref,
+              supercomponent.cssNode->style.dimensions[CSS_WIDTH],
+              supercomponent.cssNode->style.dimensions[CSS_HEIGHT],
+              component.type,
+              component.ref,
+              component.cssNode->style.dimensions[CSS_WIDTH],
+              component.cssNode->style.dimensions[CSS_HEIGHT]
+              ,NSStringFromClass([component class])
+              );
+    }
+//#else
+    else
+    {
+        WXLogDebug(@"flexLayout -> _recursivelyAddComponent : super:(%@,%@):[%f,%f] ,child:(%@,%@):[%f,%f],childClass:%@",
+              supercomponent.type,
+              supercomponent.ref,
+              supercomponent.flexCssNode->getStyleWidth(),
+              supercomponent.flexCssNode->getStyleHeight(),
+              component.type,
+              component.ref,
+              component.flexCssNode->getStyleWidth(),
+              component.flexCssNode->getStyleHeight()
+              ,NSStringFromClass([component class])
+              );
+    }
+//#endif
+#endif //DEBUG
+
+    
+    [supercomponent _insertSubcomponent:component atIndex:index];
+    // use _lazyCreateView to forbid component like cell's view creating
+    if(supercomponent && component && supercomponent->_lazyCreateView) {
+        component->_lazyCreateView = YES;
+    }
+    
+    [self recordMaximumVirtualDom:component];
+    
+    if (!component->_isTemplate) {
+        __weak typeof(self) weakSelf = self;
+        BOOL isFSCreateFinish = [self weexInstance].isJSCreateFinish;
+        [self _addUITask:^{
+            [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:componentData[@"ref"] className:nil name:componentData[@"type"] phase:WXTracingBegin functionName:@"addElement" options:@{@"threadName":WXTUIThread}];
+            [supercomponent insertSubview:component atIndex:index];
+            [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:componentData[@"ref"] className:nil name:componentData[@"type"] phase:WXTracingEnd functionName:@"addElement" options:@{@"threadName":WXTUIThread}];
+            [weakSelf onElementChange:isFSCreateFinish];
+        }];
+    }
+    
+    NSArray *subcomponentsData = [componentData valueForKey:@"children"];
+    
+    BOOL appendTree = !appendingInTree && [component.attributes[@"append"] isEqualToString:@"tree"];
+    // if ancestor is appending tree, child should not be laid out again even it is appending tree.
+    for(NSDictionary *subcomponentData in subcomponentsData){
+        [self _recursivelyAddComponent:subcomponentData toSupercomponent:component atIndex:-1 appendingInTree:appendTree || appendingInTree];
+    }
+    
+    [component _didInserted];
+    
+    if (appendTree) {
+        // If appending treeļ¼Œforce layout in case of too much tasks piling up in syncQueue
+        [self _layoutAndSyncUI];
+    }
+}
+
+- (void)moveComponent:(NSString *)ref toSuper:(NSString *)superRef atIndex:(NSInteger)index
+{
+    WXAssertComponentThread();
+    WXAssertParam(ref);
+    WXAssertParam(superRef);
+    
+    WXComponent *component = [_indexDict objectForKey:ref];
+    WXComponent *newSupercomponent = [_indexDict objectForKey:superRef];
+    WXAssertComponentExist(component);
+    WXAssertComponentExist(newSupercomponent);
+    
+    if (component.supercomponent == newSupercomponent && [newSupercomponent.subcomponents indexOfObject:component] < index) {
+        // if the supercomponent moved to is the same as original supercomponent,
+        // unify it into the index after removing.
+        index--;
+    }
+    
+    [component _moveToSupercomponent:newSupercomponent atIndex:index];
+    __weak typeof(self) weakSelf = self;
+    [self _addUITask:^{
+        [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:ref className:nil name:nil phase:WXTracingBegin functionName:@"addElement" options:@{@"threadName":WXTUIThread}];
+        [component moveToSuperview:newSupercomponent atIndex:index];
+        [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:ref className:nil name:nil phase:WXTracingEnd functionName:@"addElement" options:@{@"threadName":WXTUIThread}];
+    }];
+}
+
+- (void)removeComponent:(NSString *)ref
+{
+    WXAssertComponentThread();
+    WXAssertParam(ref);
+    
+    WXComponent *component = [_indexDict objectForKey:ref];
+    WXAssertComponentExist(component);
+    
+    if ([WXComponent isUseFlex] && !component) {
+        WXLogWarning(@"removeComponent ref from js never exit ! check JS action, ref :%@",ref);
+        return;
+    }
+    
+    [component _removeFromSupercomponent];
+    
+    [_indexDict removeObjectForKey:ref];
+    
+    __weak typeof(self) weakSelf = self;
+    BOOL isFSCreateFinish = [self weexInstance].isJSCreateFinish;
+    [self _addUITask:^{
+        [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:ref className:nil name:nil phase:WXTracingBegin functionName:@"removeElement" options:@{@"threadName":WXTUIThread}];
+        if (component.supercomponent) {
+            [component.supercomponent willRemoveSubview:component];
+        }
+        [component removeFromSuperview];
+        [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:ref className:nil name:nil phase:WXTracingEnd functionName:@"removeElement" options:@{@"threadName":WXTUIThread}];
+        [weakSelf onElementChange:isFSCreateFinish];
+    }];
+    
+    [self _checkFixedSubcomponentToRemove:component];
+    
+}
+
+- (void)onElementChange:(BOOL)isFSCreateFinish
+{
+    if (!isFSCreateFinish) {
+        return;
+    }
+    
+    UIView *root = [self weexInstance].rootView;
+    BOOL hasEvent = TRUE;
+    if (root && [root isKindOfClass:[WXRootView class]]) {
+        WXRootView* wxRootView = (WXRootView *)root;
+        hasEvent = [wxRootView isHasEvent];
+    }
+    if (hasEvent) {
+        return;
+    }
+    double current = CACurrentMediaTime()*1000;
+    
+    double diff =  current - [self weexInstance].performance.jsCreateFinishTime;
+    if (diff > 8000) {
+        return;
+    }
+    [self weexInstance].performance.interactionTime = current - self.weexInstance.performance.renderTimeOrigin;
+}
+
+- (void)recordMaximumVirtualDom:(WXComponent*) component
+{
+    WXAssertComponentExist(component);
+    if(!component){
+        return;
+    }
+    int maxDeep =0;
+    while (component) {
+        maxDeep++;
+        component = component.supercomponent;
+    }
+    if(maxDeep > [self weexInstance].performance.maxVdomDeep)
+    {
+        [self weexInstance].performance.maxVdomDeep = maxDeep;
+    }
+   
+}
+
+- (void)_checkFixedSubcomponentToRemove:(WXComponent *)component
+{
+    for (WXComponent *subcomponent in component.subcomponents) {
+        if (subcomponent->_positionType == WXPositionTypeFixed) {
+             [self _addUITask:^{
+                 [subcomponent removeFromSuperview];
+             }];
+        }
+        
+        [self _checkFixedSubcomponentToRemove:subcomponent];
+    }
+}
+
+- (WXComponent *)componentForRef:(NSString *)ref
+{
+    WXAssertComponentThread();
+    
+    return [_indexDict objectForKey:ref];
+}
+
+- (WXComponent *)componentForRoot
+{
+    return _rootComponent;
+}
+
+- (NSUInteger)numberOfComponents
+{
+    WXAssertComponentThread();
+    
+    return _indexDict.count;
+}
+
+- (WXComponent *)_buildComponentForData:(NSDictionary *)data supercomponent:(WXComponent *)supercomponent
+{
+    NSString *ref = data[@"ref"];
+    NSString *type = data[@"type"];
+    NSDictionary *styles = data[@"style"];
+    NSDictionary *attributes = data[@"attr"];
+    NSArray *events = data[@"event"];
+    
+    if (self.weexInstance.needValidate) {
+        id<WXValidateProtocol> validateHandler = [WXHandlerFactory handlerForProtocol:@protocol(WXValidateProtocol)];
+        if (validateHandler) {
+            WXComponentValidateResult* validateResult;
+            if ([validateHandler respondsToSelector:@selector(validateWithWXSDKInstance:component:supercomponent:)]) {
+                validateResult = [validateHandler validateWithWXSDKInstance:self.weexInstance component:type supercomponent:supercomponent];
+            }
+            if (validateResult==nil || !validateResult.isSuccess) {
+                type = validateResult.replacedComponent? validateResult.replacedComponent : @"div";
+                WXLogError(@"%@",[validateResult.error.userInfo objectForKey:@"errorMsg"]);
+            }
+        }
+    }
+    
+    WXComponentConfig *config = [WXComponentFactory configWithComponentName:type];
+    BOOL isTemplate = [config.properties[@"isTemplate"] boolValue] || (supercomponent && supercomponent->_isTemplate);
+    NSDictionary *bindingStyles;
+    NSDictionary *bindingAttibutes;
+    NSDictionary *bindingEvents;
+    NSDictionary *bindingProps;
+    if (isTemplate) {
+        bindingProps = [self _extractBindingProps:&attributes];
+        bindingStyles = [self _extractBindings:&styles];
+        bindingAttibutes = [self _extractBindings:&attributes];
+        bindingEvents = [self _extractBindingEvents:&events];
+    }
+    
+    Class clazz = NSClassFromString(config.clazz);;
+    WXComponent *component = [[clazz alloc] initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:self.weexInstance];
+    if (isTemplate) {
+        component->_isTemplate = YES;
+        [component _storeBindingsWithProps:bindingProps styles:bindingStyles attributes:bindingAttibutes events:bindingEvents];
+    }
+
+    WXAssert(component, @"Component build failed for data:%@", data);
+    
+    [_indexDict setObject:component forKey:component.ref];
+    [component readyToRender];// notify redyToRender event when init
+    return component;
+}
+
+- (void)addComponent:(WXComponent *)component toIndexDictForRef:(NSString *)ref
+{
+    [_indexDict setObject:component forKey:ref];
+}
+
+- (NSDictionary *)_extractBindings:(NSDictionary **)attributesOrStylesPoint
+{
+    NSDictionary *attributesOrStyles = *attributesOrStylesPoint;
+    if (!attributesOrStyles) {
+        return nil;
+    }
+    
+    NSMutableDictionary *newAttributesOrStyles = [attributesOrStyles mutableCopy];
+    NSMutableDictionary *bindingAttributesOrStyles = [NSMutableDictionary dictionary];
+    
+    [attributesOrStyles enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull attributeOrStyleName, id  _Nonnull attributeOrStyle, BOOL * _Nonnull stop) {
+        if ([WXBindingMatchIdentify isEqualToString:attributeOrStyleName] // match
+            ||  [WXBindingRepeatIdentify isEqualToString:attributeOrStyleName] // repeat
+            ||  [WXBindingOnceIdentify isEqualToString:attributeOrStyleName] // once
+            ||([attributeOrStyle isKindOfClass:[NSDictionary class]] && attributeOrStyle[WXBindingIdentify])) {  // {"attributeOrStyleName": {"@binding":"bindingExpression"}
+            bindingAttributesOrStyles[attributeOrStyleName] = attributeOrStyle;
+            [newAttributesOrStyles removeObjectForKey:attributeOrStyleName];
+        } else if ([attributeOrStyle isKindOfClass:[NSArray class]]) {
+            // {"attributeOrStyleName":[..., "string", {"@binding":"bindingExpression"}, "string", {"@binding":"bindingExpression"}, ...]
+            __block BOOL isBinding = NO;
+            [attributeOrStyle enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+                if ([obj isKindOfClass:[NSDictionary class]] && obj[WXBindingIdentify]) {
+                    isBinding = YES;
+                    *stop = YES;
+                }
+            }];
+            
+            if (isBinding) {
+                bindingAttributesOrStyles[attributeOrStyleName] = attributeOrStyle;
+                [newAttributesOrStyles removeObjectForKey:attributeOrStyleName];
+            }
+        }
+    }];
+    
+    *attributesOrStylesPoint = newAttributesOrStyles;
+    
+    return bindingAttributesOrStyles;
+}
+
+- (NSDictionary *)_extractBindingEvents:(NSArray **)eventsPoint
+{
+    NSArray *events = *eventsPoint;
+    NSMutableArray *newEvents = [events mutableCopy];
+    NSMutableDictionary *bindingEvents = [NSMutableDictionary dictionary];
+    [events enumerateObjectsUsingBlock:^(id  _Nonnull event, NSUInteger idx, BOOL * _Nonnull stop) {
+        if ([event isKindOfClass:[NSDictionary class]] && event[@"type"] && event[@"params"]) {
+            NSString *eventName = event[@"type"];
+            NSString *bindingParams = event[@"params"];
+            bindingEvents[eventName] = bindingParams;
+            newEvents[idx] = eventName;
+        }
+    }];
+    
+    *eventsPoint = newEvents;
+    return bindingEvents;
+}
+
+- (NSDictionary *)_extractBindingProps:(NSDictionary **)attributesPoint
+{
+    NSDictionary *attributes = *attributesPoint;
+    if (attributes[@"@componentProps"]) {
+        NSMutableDictionary *newAttributes = [attributes mutableCopy];
+        [newAttributes removeObjectForKey:@"@componentProps"];
+        *attributesPoint = newAttributes;
+        return attributes[@"@componentProps"];
+    }
+    
+    return nil;
+}
+
+#pragma mark Reset
+-(BOOL)isShouldReset:(id )value
+{
+    if([value isKindOfClass:[NSString class]]) {
+        if(!value || [@"" isEqualToString:value]) {
+            return YES;
+        }
+    }
+    return NO;
+}
+
+-(void)filterStyles:(NSDictionary *)styles normalStyles:(NSMutableDictionary *)normalStyles resetStyles:(NSMutableArray *)resetStyles
+{
+    for (NSString *key in styles) {
+        id value = [styles objectForKey:key];
+        if([self isShouldReset:value]) {
+            [resetStyles addObject:key];
+        }else{
+            [normalStyles setObject:styles[key] forKey:key];
+        }
+    }
+}
+
+- (void)updateStyles:(NSDictionary *)styles forComponent:(NSString *)ref
+{
+    [self handleStyles:styles forComponent:ref isUpdateStyles:YES];
+}
+
+- (void)updatePseudoClassStyles:(NSDictionary *)styles forComponent:(NSString *)ref
+{
+    [self handleStyles:styles forComponent:ref isUpdateStyles:NO];
+}
+
+- (void)handleStyleOnMainThread:(NSDictionary*)styles forComponent:(WXComponent *)component isUpdateStyles:(BOOL)isUpdateStyles
+{
+    WXAssertParam(styles);
+    WXAssertParam(component);
+    WXAssertMainThread();
+    
+    NSMutableDictionary *normalStyles = [NSMutableDictionary new];
+    NSMutableArray *resetStyles = [NSMutableArray new];
+    [self filterStyles:styles normalStyles:normalStyles resetStyles:resetStyles];
+    [component _updateStylesOnMainThread:normalStyles resetStyles:resetStyles];
+    [component readyToRender];
+    
+    WXPerformBlockOnComponentThread(^{
+        [component _updateStylesOnComponentThread:normalStyles resetStyles:resetStyles isUpdateStyles:isUpdateStyles];
+    });
+}
+
+- (void)handleStyles:(NSDictionary *)styles forComponent:(NSString *)ref isUpdateStyles:(BOOL)isUpdateStyles
+{
+    WXAssertParam(styles);
+    WXAssertParam(ref);
+    
+    WXComponent *component = [_indexDict objectForKey:ref];
+    WXAssertComponentExist(component);
+    
+    NSMutableDictionary *normalStyles = [NSMutableDictionary new];
+    NSMutableArray *resetStyles = [NSMutableArray new];
+    [self filterStyles:styles normalStyles:normalStyles resetStyles:resetStyles];
+    [component _updateStylesOnComponentThread:normalStyles resetStyles:resetStyles isUpdateStyles:isUpdateStyles];
+    [self _addUITask:^{
+        [component _updateStylesOnMainThread:normalStyles resetStyles:resetStyles];
+        [component readyToRender];
+    }];
+}
+
+- (void)updateAttributes:(NSDictionary *)attributes forComponent:(NSString *)ref
+{
+    WXAssertParam(attributes);
+    WXAssertParam(ref);
+    
+    WXComponent *component = [_indexDict objectForKey:ref];
+    WXAssertComponentExist(component);
+    
+    [component _updateAttributesOnComponentThread:attributes];
+    __weak typeof(self) weakSelf = self;
+    [self _addUITask:^{
+        [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:ref className:nil name:nil phase:WXTracingBegin functionName:@"updateAttrs" options:@{@"threadName":WXTUIThread}];
+        [component _updateAttributesOnMainThread:attributes];
+        [component readyToRender];
+        [WXTracingManager startTracingWithInstanceId:weakSelf.weexInstance.instanceId ref:ref className:nil name:nil phase:WXTracingEnd functionName:@"updateAttrs" options:@{@"threadName":WXTUIThread}];
+    }];
+}
+
+- (void)addEvent:(NSString *)eventName toComponent:(NSString *)ref
+{
+    WXAssertComponentThread();
+    WXAssertParam(eventName);
+    WXAssertParam(ref);
+    
+    WXComponent *component = [_indexDict objectForKey:ref];
+    WXAssertComponentExist(component);
+    
+    [component _addEventOnComponentThread:eventName];
+    
+    [self _addUITask:^{
+        [component _addEventOnMainThread:eventName];
+    }];
+}
+
+- (void)removeEvent:(NSString *)eventName fromComponent:(NSString *)ref
+{
+    WXAssertComponentThread();
+    WXAssertParam(eventName);
+    WXAssertParam(ref);
+    
+    WXComponent *component = [_indexDict objectForKey:ref];
+    WXAssertComponentExist(component);
+    
+    [component _removeEventOnComponentThread:eventName];
+    
+    [self _addUITask:^{
+        [component _removeEventOnMainThread:eventName];
+    }];
+}
+
+- (void)scrollToComponent:(NSString *)ref options:(NSDictionary *)options
+{
+    WXAssertComponentThread();
+    WXAssertParam(ref);
+    
+    WXComponent *toComponent = [_indexDict objectForKey:ref];
+    WXAssertComponentExist(toComponent);
+
+    id<WXScrollerProtocol> scrollerComponent = toComponent.ancestorScroller;
+    if (!scrollerComponent) {
+        return;
+    }
+
+    CGFloat offset = [[options objectForKey:@"offset"] floatValue];
+    BOOL animated = YES;
+    if ([options objectForKey:@"animated"]) {
+        animated = [[options objectForKey:@"animated"] boolValue];
+    }
+    
+    [self _addUITask:^{
+        [scrollerComponent scrollToComponent:toComponent withOffset:offset animated:animated];
+    }];
+}
+
+#pragma mark Life Cycle
+
+- (void)createFinish
+{
+    WXAssertComponentThread();
+    
+    WXSDKInstance *instance  = self.weexInstance;
+    [self _addUITask:^{
+        UIView *rootView = instance.rootView;
+        
+        //WX_MONITOR_INSTANCE_PERF_END(WXPTFirstScreenRender, instance);
+        WX_MONITOR_INSTANCE_PERF_END(WXPTAllRender, instance);
+        WX_MONITOR_SUCCESS(WXMTJSBridge);
+        WX_MONITOR_SUCCESS(WXMTNativeRender);
+        
+        if(instance.renderFinish){
+            [WXTracingManager startTracingWithInstanceId:instance.instanceId ref:nil className:nil name:nil phase:WXTracingInstant functionName:WXTRenderFinish options:@{@"threadName":WXTUIThread}];
+            instance.renderFinish(rootView);
+        }
+    }];
+    [instance updatePerDicAfterCreateFinish];
+}
+
+- (void)updateFinish
+{
+    WXAssertComponentThread();
+    
+    WXSDKInstance *instance = self.weexInstance;
+    WXComponent *root = [_indexDict objectForKey:WX_SDK_ROOT_REF];
+    
+    [self _addUITask:^{
+        if(instance.updateFinish){
+            instance.updateFinish(root.view);
+        }
+    }];
+}
+
+- (void)refreshFinish
+{
+    WXAssertComponentThread();
+    
+    WXSDKInstance *instance = self.weexInstance;
+    WXComponent *root = [_indexDict objectForKey:WX_SDK_ROOT_REF];
+    
+    [self _addUITask:^{
+        if(instance.refreshFinish){
+            instance.refreshFinish(root.view);
+        }
+    }];
+}
+
+- (void)unload
+{
+    WXAssertComponentThread();
+    [self invalidate];
+    [self _stopDisplayLink];
+    NSEnumerator *enumerator = [[_indexDict copy] objectEnumerator];
+    dispatch_async(dispatch_get_main_queue(), ^{
+        WXComponent *component;
+        while ((component = [enumerator nextObject])) {
+            [component _unloadViewWithReusing:NO];
+        }
+        _rootComponent = nil;
+    });
+    
+    [_indexDict removeAllObjects];
+    [_uiTaskQueue removeAllObjects];
+}
+
+- (void)invalidate
+{
+    _isValid = NO;
+}
+
+- (BOOL)isValid
+{
+    return _isValid;
+}
+
+#pragma mark Layout Batch
+
+- (void)_startDisplayLink
+{
+    WXAssertComponentThread();
+    
+    if(!_displayLink){
+        _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_handleDisplayLink)];
+        [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+    }
+}
+
+- (void)_stopDisplayLink
+{
+    WXAssertComponentThread();
+    
+    if(_displayLink){
+        [_displayLink invalidate];
+        _displayLink = nil;
+    }
+}
+
+- (void)_suspendDisplayLink
+{
+    WXAssertComponentThread();
+    
+    if(_displayLink && !_displayLink.paused) {
+        _displayLink.paused = YES;
+    }
+}
+
+- (void)_awakeDisplayLink
+{
+    WXAssertComponentThread();
+    
+    if(_displayLink && _displayLink.paused) {
+        _displayLink.paused = NO;
+    }
+}
+
+- (void)_handleDisplayLink
+{
+    WXAssertComponentThread();
+    
+    [self _layoutAndSyncUI];
+}
+
+- (void)_layoutAndSyncUI
+{
+    [self _layout];
+    if(_uiTaskQueue.count > 0){
+        [self _syncUITasks];
+        _noTaskTickCount = 0;
+    } else {
+        // suspend display link when there's no task for 1 second, in order to save CPU time.
+        _noTaskTickCount ++;
+        if (_noTaskTickCount > 60) {
+            [self _suspendDisplayLink];
+        }
+    }
+}
+
+- (void)_layout
+{
+    BOOL needsLayout = NO;
+
+//    NSEnumerator *enumerator = [_indexDict objectEnumerator];
+//    WXComponent *component;
+//    while ((component = [enumerator nextObject])) {
+//        if ([component needsLayout]) {
+//            needsLayout = YES;
+//            break;
+//        }
+//    }
+    
+    needsLayout = [_rootComponent needsLayout];
+
+    if (!needsLayout) {
+        return;
+    }
+#ifdef DEBUG
+    WXLogDebug(@"flexLayout -> action__ calculateLayout root");
+#endif
+    
+//#ifndef USE_FLEX
+    if(![WXComponent isUseFlex])
+    {
+         layoutNode(_rootCSSNode, _rootCSSNode->style.dimensions[CSS_WIDTH], _rootCSSNode->style.dimensions[CSS_HEIGHT], CSS_DIRECTION_INHERIT);
+    }
+//#else
+    else
+    {
+        std::pair<float, float> renderPageSize;
+        renderPageSize.first = self.weexInstance.frame.size.width;
+        renderPageSize.second = self.weexInstance.frame.size.height;
+        _rootFlexCSSNode->calculateLayout(renderPageSize);
+    }
+//#endif
+    NSMutableSet<WXComponent *> *dirtyComponents = [NSMutableSet set];
+    [_rootComponent _calculateFrameWithSuperAbsolutePosition:CGPointZero gatherDirtyComponents:dirtyComponents];
+    [self _calculateRootFrame];
+  
+    for (WXComponent *dirtyComponent in dirtyComponents) {
+        [self _addUITask:^{
+            [dirtyComponent _layoutDidFinish];
+        }];
+    }
+}
+
+//#ifdef USE_FLEX
+- (void) _printFlexComonentFrame:(WXComponent *)component
+{
+#ifdef DEBUG
+    WXLogDebug(@"node ref:%@, type:%@ , frame:%@",
+          component.ref,
+          component.type,
+          NSStringFromCGRect(component.view.layer.frame)
+          );
+#endif
+    
+  
+    
+    for (WXComponent *childComponent in component.subcomponents) {
+        [self _printFlexComonentFrame:childComponent];
+    }
+
+    
+}
+//#endif
+
+- (void)_syncUITasks
+{
+    NSArray<dispatch_block_t> *blocks = _uiTaskQueue;
+    _uiTaskQueue = [NSMutableArray array];
+    dispatch_async(dispatch_get_main_queue(), ^{
+        for(dispatch_block_t block in blocks) {
+            block();
+        }
+    });
+}
+//#ifndef USE_FLEX
+- (void)_initRootCSSNode
+{
+    _rootCSSNode = new_css_node();
+    
+    [self _applyRootFrame:self.weexInstance.frame toRootCSSNode:_rootCSSNode];
+    
+    _rootCSSNode->style.flex_wrap = CSS_NOWRAP;
+    _rootCSSNode->is_dirty = rootNodeIsDirty;
+    _rootCSSNode->get_child = rootNodeGetChild;
+    _rootCSSNode->context=(__bridge void *)(self);
+    _rootCSSNode->children_count = 1;
+}
+//#else
+- (void)_initRootFlexCssNode
+{
+    _rootFlexCSSNode = new WeexCore::WXCoreLayoutNode();
+    [self _applyRootFrame:self.weexInstance.frame];
+    _rootFlexCSSNode->setFlexWrap(WeexCore::kNoWrap);
+    _rootFlexCSSNode->setContext((__bridge void *)(self));
+}
+//#endif
+
+- (void)_calculateRootFrame
+{
+//#ifndef USE_FLEX
+    
+    if(![WXComponent isUseFlex])
+    {
+        if (!_rootCSSNode->layout.should_update) {
+            return;
+        }
+        _rootCSSNode->layout.should_update = false;
+#ifdef DEBUG
+        WXLogDebug(@"flexLayout -> root _calculateRootFrame");
+#endif
+        
+        CGRect frame = CGRectMake(WXRoundPixelValue(_rootCSSNode->layout.position[CSS_LEFT]),
+                                  WXRoundPixelValue(_rootCSSNode->layout.position[CSS_TOP]),
+                                  WXRoundPixelValue(_rootCSSNode->layout.dimensions[CSS_WIDTH]),
+                                  WXRoundPixelValue(_rootCSSNode->layout.dimensions[CSS_HEIGHT]));
+        WXPerformBlockOnMainThread(^{
+            if(!self.weexInstance.isRootViewFrozen) {
+                self.weexInstance.rootView.frame = frame;
+            }
+        });
+        
+        resetNodeLayout(_rootCSSNode);
+    }
+//#else
+    else
+    {
+        if(!_rootFlexCSSNode->hasNewLayout()){
+            return;
+        }
+        _rootFlexCSSNode->setHasNewLayout(false);
+#ifdef DEBUG
+        WXLogDebug(@"flexLayout -> root _calculateRootFrame");
+#endif
+        
+        
+        CGRect frame = CGRectMake(WXRoundPixelValue(_rootFlexCSSNode->getLayoutPositionLeft()),
+                                  WXRoundPixelValue(_rootFlexCSSNode->getLayoutPositionTop()),
+                                  WXRoundPixelValue(_rootFlexCSSNode->getLayoutWidth()),
+                                  WXRoundPixelValue(_rootFlexCSSNode->getLayoutHeight()));
+        WXPerformBlockOnMainThread(^{
+            if(!self.weexInstance.isRootViewFrozen) {
+                self.weexInstance.rootView.frame = frame;
+            }
+        });
+        //   _rootFlexCSSNode->reset();
+        
+        //    resetNodeLayout(_rootFlexCSSNode);
+    }
+//#endif
+    
+   
+}
+
+
+#pragma mark Fixed 
+
+- (void)addFixedComponent:(WXComponent *)fixComponent
+{
+    [_fixedComponents addObject:fixComponent];
+//#ifndef USE_FLEX
+    if(![WXComponent isUseFlex])
+    {
+        _rootCSSNode->children_count = (int)[_fixedComponents count] + 1;
+    }
+//#else
+    else
+    {
+        _rootFlexCSSNode->addChildAt(fixComponent.flexCssNode, (uint32_t)([_fixedComponents count]-1));
+    }
+//#endif
+}
+
+- (void)removeFixedComponent:(WXComponent *)fixComponent
+{
+    [_fixedComponents removeObject:fixComponent];
+//#ifndef USE_FLEX
+    if(![WXComponent isUseFlex])
+    {
+        _rootCSSNode->children_count = (int)[_fixedComponents count] + 1;
+    }
+//#else
+    else
+    {
+        _rootFlexCSSNode->removeChild(fixComponent->_flexCssNode);
+    }
+//#endif
+}
+
+@end
+
+void WXPerformBlockOnComponentThread(void (^block)(void))
+{
+    [WXComponentManager _performBlockOnComponentThread:block];
+}
+
+void WXPerformBlockSyncOnComponentThread(void (^block)(void))
+{
+    [WXComponentManager _performBlockSyncOnComponentThread:block];
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b77b4259/ios/sdk/WeexSDK/Sources/Model/WXComponent.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.h b/ios/sdk/WeexSDK/Sources/Model/WXComponent.h
index 5e8ba70..c0e6c9a 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.h
+++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.h
@@ -17,6 +17,12 @@
  * under the License.
  */
 
+/**
+ *  def : use weex_flex_engin
+ *  ndef: use yoga
+ **/
+
+
 #import <Foundation/Foundation.h>
 #import "WXLayoutDefine.h"
 #import "WXType.h"
@@ -143,13 +149,6 @@ NS_ASSUME_NONNULL_BEGIN
 //@property(nonatomic, assign) CGPoint absolutePosition;
 
 /**
- * @abstract Return the css node used to layout.
- *
- * @warning Subclasses must not override this.
- */
-@property(nonatomic, readonly, assign) css_node_t *cssNode;
-
-/**
  * @abstract Invalidates the component's layout and marks it as needing an update.
  *
  * @discussion You can call this method to indicate that the layout of a component has changed and must be updated. Weex typically calls this method automatically when the layout-related styles change or when subcomponents are added or removed.

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b77b4259/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.m b/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
deleted file mode 100644
index 300dbc9..0000000
--- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
+++ /dev/null
@@ -1,842 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#import "WXComponent.h"
-#import "WXComponent_internal.h"
-#import "WXComponentManager.h"
-#import "WXSDKManager.h"
-#import "WXSDKInstance.h"
-#import "WXSDKInstance_private.h"
-#import "WXDefine.h"
-#import "WXLog.h"
-#import "WXWeakObjectWrapper.h"
-#import "WXUtility.h"
-#import "WXConvert.h"
-#import "WXMonitor.h"
-#import "WXAssert.h"
-#import "WXThreadSafeMutableDictionary.h"
-#import "WXThreadSafeMutableArray.h"
-#import "WXTransform.h"
-#import "WXRoundedRect.h"
-#import <pthread/pthread.h>
-#import "WXComponent+PseudoClassManagement.h"
-#import "WXComponent+BoxShadow.h"
-#import "WXTracingManager.h"
-#import "WXComponent+Events.h"
-
-#pragma clang diagnostic ignored "-Wincomplete-implementation"
-#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
-
-@interface WXComponent () <UIGestureRecognizerDelegate>
-
-@end
-
-@implementation WXComponent
-{
-@private
-    NSString *_ref;
-    NSMutableDictionary *_styles;
-    NSMutableDictionary *_attributes;
-    NSMutableArray *_events;
-    
-    // Protects properties styles/attributes/events/subcomponents which will be accessed from multiple threads.
-    pthread_mutex_t _propertyMutex;
-    pthread_mutexattr_t _propertMutexAttr;
-    
-    __weak WXComponent *_supercomponent;
-    __weak id<WXScrollerProtocol> _ancestorScroller;
-    __weak WXSDKInstance *_weexInstance;
-}
-
-#pragma mark Life Cycle
-
-- (instancetype)initWithRef:(NSString *)ref
-                       type:(NSString *)type
-                     styles:(NSDictionary *)styles
-                 attributes:(NSDictionary *)attributes
-                     events:(NSArray *)events
-               weexInstance:(WXSDKInstance *)weexInstance
-{
-    if (self = [super init]) {
-        pthread_mutexattr_init(&_propertMutexAttr);
-        pthread_mutexattr_settype(&_propertMutexAttr, PTHREAD_MUTEX_RECURSIVE);
-        pthread_mutex_init(&_propertyMutex, &_propertMutexAttr);
-        
-        _ref = ref;
-        _type = type;
-        _weexInstance = weexInstance;
-        _componentType = WXComponentTypeCommon;
-        _styles = [self parseStyles:styles];
-        _attributes = attributes ? [NSMutableDictionary dictionaryWithDictionary:attributes] : [NSMutableDictionary dictionary];
-        _events = events ? [NSMutableArray arrayWithArray:events] : [NSMutableArray array];
-        _subcomponents = [NSMutableArray array];
-        _absolutePosition = CGPointMake(NAN, NAN);
-        
-        _displayType = WXDisplayTypeBlock;
-        _isNeedJoinLayoutSystem = YES;
-        _isLayoutDirty = YES;
-        _isViewFrameSyncWithCalculated = YES;
-        _ariaHidden = nil;
-        _accessible = nil;
-        _accessibilityHintContent = nil;
-        
-        _async = NO;
-        
-        if (styles[kWXTransitionProperty]) {
-            _transition = [[WXTransition alloc]initWithStyles:styles];
-        }
-
-        //TODO set indicator style 
-        if ([type isEqualToString:@"indicator"]) {
-            _styles[@"position"] = @"absolute";
-            if (!_styles[@"left"] && !_styles[@"right"]) {
-                _styles[@"left"] = @0.0f;
-            }
-            if (!_styles[@"top"] && !_styles[@"bottom"]) {
-                _styles[@"top"] = @0.0f;
-            }
-        }
-        
-        if (attributes[@"ariaHidden"]) {
-            
-            _ariaHidden = [WXConvert NSString:attributes[@"ariaHidden"]];
-        }
-        if (attributes[@"role"]) {
-            _roles = attributes[@"role"];
-        }
-        if (attributes[@"ariaLabel"]) {
-            _ariaLabel = [WXConvert NSString:attributes[@"ariaLabel"]];
-        }
-        if (attributes[@"accessible"]) {
-            _accessible = [WXConvert NSString:attributes[@"accessible"]];
-        }
-        if(attributes[@"accessibilityHint"]) {
-            _accessibilityHintContent = [WXConvert NSString:attributes[@"accessibilityHint"]];
-        }
-        if (attributes[@"groupAccessibilityChildren"]) {
-            _groupAccessibilityChildren = [WXConvert NSString:attributes[@"groupAccessibilityChildren"]];
-        }
-        
-        if (attributes[@"testId"]) {
-            _testId = [WXConvert NSString:attributes[@"testId"]];
-        }
-        
-        [self _setupNavBarWithStyles:_styles attributes:_attributes];
-        [self _initCSSNodeWithStyles:_styles];
-        [self _initViewPropertyWithStyles:_styles];
-        [self _initCompositingAttribute:_attributes];
-        [self _handleBorders:styles isUpdating:NO];
-        
-    }
-    
-    return self;
-}
-
-- (id)copyWithZone:(NSZone *)zone
-{
-    NSInteger copyId = 0;
-    @synchronized(self){
-        static NSInteger __copy = 0;
-        copyId = __copy % (1024*1024);
-        __copy++;
-    }
-    NSString *copyRef = [NSString stringWithFormat:@"%ldcopy_of%@", (long)copyId, _isTemplate ? self.ref : self->_templateComponent.ref];
-    WXComponent *component = [[[self class] allocWithZone:zone] initWithRef:copyRef type:self.type styles:self.styles attributes:self.attributes events:self.events weexInstance:self.weexInstance];
-    if (_isTemplate) {
-        component->_templateComponent = self;
-    } else {
-        component->_templateComponent = self->_templateComponent;
-    }
-    memcpy(component->_cssNode, self.cssNode, sizeof(css_node_t));
-    component->_cssNode->context = (__bridge void *)component;
-    component->_calculatedFrame = self.calculatedFrame;
-    
-    NSMutableArray *subcomponentsCopy = [NSMutableArray array];
-    for (WXComponent *subcomponent in self.subcomponents) {
-        WXComponent *subcomponentCopy = [subcomponent copy];
-        subcomponentCopy->_supercomponent = component;
-        [subcomponentsCopy addObject:subcomponentCopy];
-    }
-    
-    component->_subcomponents = subcomponentsCopy;
-    
-    WXPerformBlockOnComponentThread(^{
-        [self.weexInstance.componentManager addComponent:component toIndexDictForRef:copyRef];
-    });
-    
-    return component;
-}
-
-- (UIAccessibilityTraits)_parseAccessibilityTraitsWithTraits:(UIAccessibilityTraits)trait roles:(NSString*)roleStr
-{
-    UIAccessibilityTraits newTrait = trait;
-    for (NSString * role in [roleStr componentsSeparatedByString:@" "]) {
-        newTrait |= [WXConvert WXUIAccessibilityTraits: role];
-    }
-    
-    return newTrait;
-}
-
-- (void)dealloc
-{
-    free_css_node(_cssNode);
-
-//    [self _removeAllEvents];
-    // remove all gesture and all
-    if (_isTemplate && self.attributes[@"@templateId"]) {
-        [[WXSDKManager bridgeMgr] callComponentHook:_weexInstance.instanceId componentId:self.attributes[@"@templateId"] type:@"lifecycle" hook:@"destroy" args:nil competion:nil];
-    }
-    if (_tapGesture) {
-        [_tapGesture removeTarget:nil action:NULL];
-    }
-    if ([_swipeGestures count]) {
-        for (UISwipeGestureRecognizer *swipeGestures in _swipeGestures) {
-            [swipeGestures removeTarget:nil action:NULL];
-        }
-    }
-    
-    if (_longPressGesture) {
-        [_longPressGesture removeTarget:nil action:NULL];
-    }
-    
-    if (_panGesture) {
-        [_panGesture removeTarget:nil action:NULL];
-    }
-    
-    if (_positionType == WXPositionTypeFixed) {
-        [self.weexInstance.componentManager removeFixedComponent:self];
-    }
-
-    pthread_mutex_destroy(&_propertyMutex);
-    pthread_mutexattr_destroy(&_propertMutexAttr);
-
-}
-
-- (NSDictionary *)styles
-{
-    NSDictionary *styles;
-    pthread_mutex_lock(&_propertyMutex);
-    styles = _styles;
-    pthread_mutex_unlock(&_propertyMutex);
-    return styles;
-}
-
-- (NSDictionary *)pseudoClassStyles
-{
-    NSDictionary *pseudoClassStyles;
-    pthread_mutex_lock(&_propertyMutex);
-    pseudoClassStyles = _pseudoClassStyles;
-    pthread_mutex_unlock(&_propertyMutex);
-    
-    return pseudoClassStyles;
-}
-
-- (NSString *)type
-{
-    return _type;
-}
-
-- (NSDictionary *)attributes
-{
-    NSDictionary *attributes;
-    pthread_mutex_lock(&_propertyMutex);
-    attributes = _attributes;
-    pthread_mutex_unlock(&_propertyMutex);
-    
-    return attributes;
-}
-
-- (NSArray *)events
-{
-    NSArray *events;
-    pthread_mutex_lock(&_propertyMutex);
-    events = [_events copy];
-    pthread_mutex_unlock(&_propertyMutex);
-    
-    return events;
-}
-
-- (void)setDisplayType:(WXDisplayType)displayType
-{
-    if (_displayType != displayType) {
-        _displayType = displayType;
-        if (displayType == WXDisplayTypeNone) {
-            _isNeedJoinLayoutSystem = NO;
-            [self.supercomponent _recomputeCSSNodeChildren];
-            WXPerformBlockOnMainThread(^{
-                [self removeFromSuperview];
-            });
-        } else {
-            _isNeedJoinLayoutSystem = YES;
-            [self.supercomponent _recomputeCSSNodeChildren];
-            WXPerformBlockOnMainThread(^{
-                [self _buildViewHierarchyLazily];
-                // TODO: insert into the correct index
-                [self.supercomponent.view addSubview:self.view];
-            });
-        }
-        [self setNeedsLayout];
-    }
-}
-
-- (WXSDKInstance *)weexInstance
-{
-    return _weexInstance;
-}
-
-- (NSString *)description
-{
-    return [NSString stringWithFormat:@"<%@:%p ref=%@> %@", _type, self, _ref, _view];
-}
-
-#pragma mark Property
-
-- (UIView *)view
-{
-    if (_componentType != WXComponentTypeCommon) {
-        return nil;
-    }
-    if ([self isViewLoaded]) {
-        return _view;
-    } else {
-        WXAssertMainThread();
-        
-        // compositing child will be drew by its composited ancestor
-        if (_isCompositingChild) {
-            return nil;
-        }
-        
-        [self viewWillLoad];
-        
-        _view = [self loadView];
-        
-        _layer = _view.layer;
-        _view.frame = _calculatedFrame;
-        _view.hidden = _visibility == WXVisibilityShow ? NO : YES;
-        _view.clipsToBounds = _clipToBounds;
-        if (![self _needsDrawBorder]) {
-            _layer.borderColor = _borderTopColor.CGColor;
-            _layer.borderWidth = _borderTopWidth;
-            [self _resetNativeBorderRadius];
-            _layer.opacity = _opacity;
-            _view.backgroundColor = _backgroundColor;
-        }
-
-        if (_backgroundImage) {
-            [self setGradientLayer];
-        }
-        
-        if (_transform) {
-            [_transform applyTransformForView:_view];
-        }
-        
-        if (_boxShadow) {
-            [self configBoxShadow:_boxShadow];
-        }
-        
-        _view.wx_component = self;
-        _view.wx_ref = self.ref;
-        _layer.wx_component = self;
-        
-        if (_roles) {
-            [_view setAccessibilityTraits:[self _parseAccessibilityTraitsWithTraits:self.view.accessibilityTraits roles:_roles]];
-        }
-        
-        if (_testId) {
-            _view.accessibilityIdentifier = _testId;
-        }
-        
-        if (_accessibilityHintContent) {
-            [_view setAccessibilityHint:_accessibilityHintContent];
-        }
-        
-        if (_ariaLabel) {
-            _view.accessibilityLabel = _ariaLabel;
-        }
-        if (_accessible) {
-            [_view setIsAccessibilityElement:[WXConvert BOOL:_accessible]];
-        }
-        
-        if (_ariaHidden) {
-            [_view setAccessibilityElementsHidden:[WXConvert BOOL:_ariaHidden]];
-        }
-        if (_groupAccessibilityChildren) {
-            [_view setShouldGroupAccessibilityChildren:[WXConvert BOOL:_groupAccessibilityChildren]];
-        }
-        
-        [self _initEvents:self.events];
-        [self _initPseudoEvents:_isListenPseudoTouch];
-        
-        if (_positionType == WXPositionTypeSticky) {
-            [self.ancestorScroller addStickyComponent:self];
-        }
-        
-        if (self.supercomponent && self.supercomponent->_async) {
-            self->_async = YES;
-        }
-        
-        [self setNeedsDisplay];
-        [[NSNotificationCenter defaultCenter] postNotificationName:WX_COMPONENT_NOTIFICATION_VIEW_LOADED object:self];
-        [self viewDidLoad];
-        
-        if (_lazyCreateView) {
-            [self _buildViewHierarchyLazily];
-        }
-
-        [self _handleFirstScreenTime];
-        
-        return _view;
-    }
-}
-
-- (void)_buildViewHierarchyLazily
-{
-    if (self.supercomponent && !((WXComponent *)self.supercomponent)->_lazyCreateView) {
-        NSArray *subcomponents = ((WXComponent *)self.supercomponent).subcomponents;
-        
-        NSInteger index = [subcomponents indexOfObject:self];
-        if (index != NSNotFound) {
-            [(WXComponent *)self.supercomponent insertSubview:self atIndex:index];
-        }
-    }
-    
-    NSArray *subcomponents = self.subcomponents;
-    for (int i = 0; i < subcomponents.count; i++) {
-        WXComponent *subcomponent = subcomponents[i];
-        [self insertSubview:subcomponent atIndex:i];
-    }
-}
-
-- (void)_resetNativeBorderRadius
-{
-    WXRoundedRect *borderRect = [[WXRoundedRect alloc] initWithRect:_calculatedFrame topLeft:_borderTopLeftRadius topRight:_borderTopRightRadius bottomLeft:_borderBottomLeftRadius bottomRight:_borderBottomRightRadius];
-    _layer.cornerRadius = borderRect.radii.topLeft;
-}
-
-- (void)_handleFirstScreenTime
-{
-    if (WX_MONITOR_INSTANCE_PERF_IS_RECORDED(WXPTFirstScreenRender, self.weexInstance)) {
-        return;
-    }
-    CGPoint absolutePosition = [self.supercomponent.view convertPoint:_view.frame.origin toView:_weexInstance.rootView];
-    if (absolutePosition.y + _view.frame.size.height > self.weexInstance.rootView.frame.size.height + 1) {
-        WX_MONITOR_INSTANCE_PERF_END(WXPTFirstScreenRender, self.weexInstance);
-    }
-}
-
-- (CALayer *)layer
-{
-    return _layer;
-}
-
-- (CGRect)calculatedFrame
-{
-    return _calculatedFrame;
-}
-
-- (CGPoint)absolutePosition
-{
-    return _absolutePosition;
-}
-
-- (css_node_t *)cssNode
-{
-    return _cssNode;
-}
-
-- (void)_addEventParams:(NSDictionary *)params
-{
-    pthread_mutex_lock(&_propertyMutex);
-    if (!_eventParameters) {
-        _eventParameters = [NSMutableDictionary dictionary];
-    }
-    [_eventParameters addEntriesFromDictionary:params];
-    pthread_mutex_unlock(&_propertyMutex);
-}
-
-- (NSArray *)_paramsForEvent:(NSString *)eventName
-{
-    NSArray *params;
-    pthread_mutex_lock(&_propertyMutex);
-    params = _eventParameters[eventName];
-    pthread_mutex_unlock(&_propertyMutex);
-    
-    return params;
-}
-
-#pragma mark Component Hierarchy 
-
-- (NSArray<WXComponent *> *)subcomponents
-{
-    NSArray<WXComponent *> *subcomponents;
-    pthread_mutex_lock(&_propertyMutex);
-    subcomponents = [_subcomponents copy];
-    pthread_mutex_unlock(&_propertyMutex);
-    
-    return subcomponents;
-}
-
-- (WXComponent *)supercomponent
-{
-    return _supercomponent;
-}
-
-- (void)_insertSubcomponent:(WXComponent *)subcomponent atIndex:(NSInteger)index
-{
-    WXAssert(subcomponent, @"The subcomponent to insert to %@ at index %d must not be nil", self, index);
-    if (index > [_subcomponents count]) {
-        WXLogError(@"the index of inserted %ld is out of range as the current is %lu", (long)index, (unsigned long)[_subcomponents count]);
-        return;
-    }
-    
-    subcomponent->_supercomponent = self;
-    
-    pthread_mutex_lock(&_propertyMutex);
-    [_subcomponents insertObject:subcomponent atIndex:index];
-    pthread_mutex_unlock(&_propertyMutex);
-    
-    if (subcomponent->_positionType == WXPositionTypeFixed) {
-        [self.weexInstance.componentManager addFixedComponent:subcomponent];
-        subcomponent->_isNeedJoinLayoutSystem = NO;
-    }
-    
-    if (_useCompositing || _isCompositingChild) {
-        subcomponent->_isCompositingChild = YES;
-    }
-    
-    [self _recomputeCSSNodeChildren];
-    [self setNeedsLayout];
-}
-
-- (void)_removeSubcomponent:(WXComponent *)subcomponent
-{
-    pthread_mutex_lock(&_propertyMutex);
-    [_subcomponents removeObject:subcomponent];
-    pthread_mutex_unlock(&_propertyMutex);
-}
-
-- (void)_removeFromSupercomponent
-{
-    [self.supercomponent _removeSubcomponent:self];
-    [self.supercomponent _recomputeCSSNodeChildren];
-    [self.supercomponent setNeedsLayout];
-    
-    if (_positionType == WXPositionTypeFixed) {
-        [self.weexInstance.componentManager removeFixedComponent:self];
-        self->_isNeedJoinLayoutSystem = YES;
-    }
-}
-
-- (void)_moveToSupercomponent:(WXComponent *)newSupercomponent atIndex:(NSUInteger)index
-{
-    [self _removeFromSupercomponent];
-    [newSupercomponent _insertSubcomponent:self atIndex:index];
-}
-
-- (void)_didInserted
-{
-    
-}
-
-- (id<WXScrollerProtocol>)ancestorScroller
-{
-    if(!_ancestorScroller) {
-        WXComponent *supercomponent = self.supercomponent;
-        while (supercomponent) {
-            if([supercomponent conformsToProtocol:@protocol(WXScrollerProtocol)]) {
-                _ancestorScroller = (id<WXScrollerProtocol>)supercomponent;
-                break;
-            }
-            supercomponent = supercomponent.supercomponent;
-        }
-    }
-    
-    return _ancestorScroller;
-}
-
-#pragma mark Updating
-- (void)_updateStylesOnComponentThread:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles isUpdateStyles:(BOOL)isUpdateStyles
-{
-    BOOL isTransitionTag = _transition ? [self _isTransitionTag:styles] : NO;
-    if (isTransitionTag) {
-        [_transition _handleTransitionWithStyles:styles resetStyles:resetStyles target:self];
-    } else {
-        styles = [self parseStyles:styles];
-        [self _updateCSSNodeStyles:styles];
-        [self _resetCSSNodeStyles:resetStyles];
-    }
-    if (isUpdateStyles) {
-        [self _modifyStyles:styles];
-        if ([self needsLayout]) {
-            // call update style may take effect on layout, maybe the component
-            // displaylink has been paused, so we need to restart the component task, and it will auto-pause when task queue is empty.
-            [self.weexInstance.componentManager startComponentTasks];
-        }
-    }
-}
-
-- (BOOL)_isTransitionTag:(NSDictionary *)styles
-{
-    BOOL yesOrNo = false;
-    if (_transition.transitionOptions != WXTransitionOptionsNone) {
-        yesOrNo = true;
-    }
-    return yesOrNo;
-}
-
-- (BOOL)_isTransitionOnMainThreadStyles:(NSDictionary *)styles
-{
-    BOOL yesOrNo = false;
-    if (_transition.transitionOptions != WXTransitionOptionsNone) {
-        if ((_transition.transitionOptions & WXTransitionOptionsBackgroundColor &&styles[@"backgroundColor"])
-            ||(_transition.transitionOptions & WXTransitionOptionsTransform &&styles[@"transform"])
-            ||(_transition.transitionOptions & WXTransitionOptionsOpacity &&styles[@"opacity"])) {
-            yesOrNo = true;
-        }
-    }
-    return yesOrNo;
-}
-
-- (void)_modifyStyles:(NSDictionary *)styles
-{
-    pthread_mutex_lock(&_propertyMutex);
-    [_styles addEntriesFromDictionary:styles];
-    pthread_mutex_unlock(&_propertyMutex);
-}
-
-- (void)_updateAttributesOnComponentThread:(NSDictionary *)attributes
-{
-    pthread_mutex_lock(&_propertyMutex);
-    [_attributes addEntriesFromDictionary:attributes];
-    pthread_mutex_unlock(&_propertyMutex);
-}
-
-- (void)_addEventOnComponentThread:(NSString *)eventName
-{
-    pthread_mutex_lock(&_propertyMutex);
-    [_events addObject:eventName];
-    pthread_mutex_unlock(&_propertyMutex);
-}
-
-- (void)_removeEventOnComponentThread:(NSString *)eventName
-{
-    pthread_mutex_lock(&_propertyMutex);
-    [_events removeObject:eventName];
-    pthread_mutex_unlock(&_propertyMutex);
-}
-
-- (void)_updateStylesOnMainThread:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles
-{
-    WXAssertMainThread();
-    if (![self _isTransitionOnMainThreadStyles:styles]) {
-        [self _updateViewStyles:styles];
-    } else {
-        [self _transitionUpdateViewProperty:styles];
-    }
-    [self _resetStyles:resetStyles];
-    [self _handleBorders:styles isUpdating:YES];
-    [self updateStyles:styles];
-    [self resetStyles:resetStyles];
-}
-
-- (void)_updateAttributesOnMainThread:(NSDictionary *)attributes
-{
-    WXAssertMainThread();
-    
-    [self _updateNavBarAttributes:attributes];
-    
-    [self updateAttributes:attributes];
-    [self _configWXComponentA11yWithAttributes:attributes];
-}
-
-- (void)updateStyles:(NSDictionary *)styles
-{
-    WXAssertMainThread();
-}
-
-- (void)updateAttributes:(NSDictionary *)attributes
-{
-    WXAssertMainThread();
-}
-
-- (void)setNativeTransform:(CGAffineTransform)transform
-{
-    WXAssertMainThread();
-    
-    _transform = [[WXTransform alloc] initWithNativeTransform:CATransform3DMakeAffineTransform(transform) instance:self.weexInstance];
-    if (!CGRectEqualToRect(self.calculatedFrame, CGRectZero)) {
-        [_transform applyTransformForView:_view];
-        [_layer setNeedsDisplay];
-    }
-}
-
-- (void)readyToRender
-{
-    if (self.weexInstance.trackComponent) {
-        [self.supercomponent readyToRender];
-    }
-}
-
-
-- (void)setGradientLayer
-{
-    if (CGRectEqualToRect(self.view.frame, CGRectZero)) {
-        return;
-    }
-    NSDictionary * linearGradient = [WXUtility linearGradientWithBackgroundImage:_backgroundImage];
-    if (!linearGradient) {
-        return ;
-    }
-    
-    __weak typeof(self) weakSelf = self;
-    dispatch_async(dispatch_get_main_queue(), ^{
-        __strong typeof(self) strongSelf = weakSelf;
-        if(strongSelf) {
-            UIColor * startColor = (UIColor*)linearGradient[@"startColor"];
-            UIColor * endColor = (UIColor*)linearGradient[@"endColor"];
-            CAGradientLayer * gradientLayer = [WXUtility gradientLayerFromColors:@[startColor, endColor] locations:nil frame:strongSelf.view.bounds gradientType:[linearGradient[@"gradientType"] integerValue]];
-            if (gradientLayer) {
-                _backgroundColor = [UIColor colorWithPatternImage:[strongSelf imageFromLayer:gradientLayer]];
-                strongSelf.view.backgroundColor = _backgroundColor;
-            }
-        }
-    });
-}
-
-- (void)_configWXComponentA11yWithAttributes:(NSDictionary *)attributes
-{
-    WX_CHECK_COMPONENT_TYPE(self.componentType)
-    if (attributes[@"role"]){
-        _roles = attributes[@"role"];
-        [self.view setAccessibilityTraits:[self _parseAccessibilityTraitsWithTraits:self.view.accessibilityTraits roles:_roles]];
-    }
-    if (attributes[@"ariaHidden"]) {
-        _ariaHidden = [WXConvert NSString:attributes[@"ariaHidden"]];
-        [self.view setAccessibilityElementsHidden:[WXConvert BOOL:_ariaHidden]];
-    }
-    if (attributes[@"accessible"]) {
-        _accessible = [WXConvert NSString:attributes[@"accessible"]];
-        [self.view setIsAccessibilityElement:[WXConvert BOOL:_accessible]];
-    }
-    if (attributes[@"ariaLabel"]) {
-        _ariaLabel = [WXConvert NSString:attributes[@"ariaLabel"]];
-        self.view.accessibilityValue = _ariaLabel;
-    }
-    if (attributes[@"accessibilityHint"]) {
-        _accessibilityHintContent = [WXConvert NSString:attributes[@"accessibilityHint"]];
-        [self.view setAccessibilityHint:_accessibilityHintContent];
-    }
-    
-    if (attributes[@"groupAccessibilityChildren"]) {
-        _groupAccessibilityChildren = [WXConvert NSString:attributes[@"groupAccessibilityChildren"]];
-        [self.view setShouldGroupAccessibilityChildren:[WXConvert BOOL:_groupAccessibilityChildren]];
-    }
-
-    
-    if (attributes[@"testId"]) {
-        [self.view setAccessibilityIdentifier:[WXConvert NSString:attributes[@"testId"]]];
-    }
-
-}
-
-- (UIImage *)imageFromLayer:(CALayer *)layer
-{
-    UIGraphicsBeginImageContextWithOptions(layer.frame.size, NO, 0);
-    [layer renderInContext:UIGraphicsGetCurrentContext()];
-    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
-    UIGraphicsEndImageContext();
-    return outputImage;
-}
-
-#pragma mark Reset
-- (void)resetStyles:(NSArray *)styles
-{
-    WXAssertMainThread();
-}
-
-#pragma mark Layout
-
-/**
- *  @see WXComponent+Layout.m
- */
-
-#pragma mark View Management
-
-/**
- *  @see WXComponent+ViewManagement.m
- */
-
-#pragma mark Events
-
-/**
- *  @see WXComponent+Events.m
- */
-
-#pragma mark Display
-
-/**
- *  @see WXComponent+Display.m
- */
-
-@end
-
-
-@implementation UIView (WXComponent)
-
-- (WXComponent *)wx_component
-{
-    WXWeakObjectWrapper *weakWrapper = objc_getAssociatedObject(self, @selector(wx_component));
-    return [weakWrapper weakObject];
-}
-
-- (void)setWx_component:(WXComponent *)wx_component
-{
-    id weakWrapper = [[WXWeakObjectWrapper alloc] initWithWeakObject:wx_component];
-    objc_setAssociatedObject(self, @selector(wx_component), weakWrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
-}
-
-- (NSString *)wx_ref
-{
-    WXWeakObjectWrapper *weakWrapper = objc_getAssociatedObject(self, @selector(wx_ref));
-    return [weakWrapper weakObject];
-}
-
-- (void)setWx_ref:(NSString *)wx_ref
-{
-    id weakWrapper = [[WXWeakObjectWrapper alloc] initWithWeakObject:wx_ref];
-    objc_setAssociatedObject(self, @selector(wx_ref), weakWrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
-}
-
-@end
-
-@implementation CALayer (WXComponents_new)
-
-- (WXComponent *)wx_component
-{
-    WXWeakObjectWrapper *weakWrapper = objc_getAssociatedObject(self, @selector(wx_component));
-    return [weakWrapper weakObject];
-}
-
-- (void)setWx_component:(WXComponent *)wx_component
-{
-    id weakWrapper = [[WXWeakObjectWrapper alloc] initWithWeakObject:wx_component];
-    objc_setAssociatedObject(self, @selector(wx_component), weakWrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
-}
-
-@end