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

[iOS] Fix problem that _backgroundColor causing multithread crashing. #2934

Merged
merged 1 commit into from
Sep 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ typedef id (^WXDataBindingBlock)(NSDictionary *data, BOOL *needUpdate);
/**
* View
*/
UIColor *_backgroundColor;
uint32_t _backgroundColor;
NSString *_backgroundImage;
NSString *_clipRadius;
WXClipType _clipToBounds;
Expand Down Expand Up @@ -114,10 +114,10 @@ typedef id (^WXDataBindingBlock)(NSDictionary *data, BOOL *needUpdate);
BOOL _isCompositingChild;
WXThreadSafeCounter *_displayCounter;

UIColor *_borderTopColor;
UIColor *_borderRightColor;
UIColor *_borderLeftColor;
UIColor *_borderBottomColor;
uint32_t _borderTopColor;
uint32_t _borderRightColor;
uint32_t _borderLeftColor;
uint32_t _borderBottomColor;

CGFloat _borderTopWidth;
CGFloat _borderRightWidth;
Expand Down
61 changes: 48 additions & 13 deletions ios/sdk/WeexSDK/Sources/Display/WXComponent+Display.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#import "UIBezierPath+Weex.h"
#import "WXRoundedRect.h"
#import "WXSDKInstance.h"
#import "WXConvert.h"

#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"

Expand Down Expand Up @@ -289,7 +290,7 @@ - (WXDisplayBlock)_compositeDisplayBlock
- (void)_collectCompositingDisplayBlocks:(NSMutableArray *)displayBlocks context:(CGContextRef)context isCancelled:(BOOL(^)(void))isCancelled
{
// TODO: compositingChild has no chance to applyPropertiesToView, need update here?
UIColor *backgroundColor = _backgroundColor;
UIColor *backgroundColor = [WXConvert UIColorFromRGBA:_backgroundColor];
BOOL clipsToBounds = _clipToBounds;
CGRect frame = self.calculatedFrame;
CGRect bounds = CGRectMake(0, 0, frame.size.width, frame.size.height);
Expand Down Expand Up @@ -349,8 +350,9 @@ - (void)_drawBorderWithContext:(CGContextRef)context size:(CGSize)size

CGContextSetAlpha(context, _opacity);
// fill background color
if (_backgroundColor && CGColorGetAlpha(_backgroundColor.CGColor) > 0) {
CGContextSetFillColorWithColor(context, _backgroundColor.CGColor);
UIColor* backgroundColor = [WXConvert UIColorFromRGBA:_backgroundColor];
if (CGColorGetAlpha(backgroundColor.CGColor) > 0) {
CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
UIBezierPath *bezierPath = [UIBezierPath wx_bezierPathWithRoundedRect:rect topLeft:topLeft topRight:topRight bottomLeft:bottomLeft bottomRight:bottomRight];
[bezierPath fill];
WXPerformBlockOnMainThread(^{
Expand All @@ -367,7 +369,7 @@ - (void)_drawBorderWithContext:(CGContextRef)context size:(CGSize)size
CGContextSetLineDash(context, 0, 0, 0);
}
CGContextSetLineWidth(context, _borderTopWidth);
CGContextSetStrokeColorWithColor(context, _borderTopColor.CGColor);
CGContextSetStrokeColorWithColor(context, [WXConvert UIColorFromRGBA:_borderTopColor].CGColor);
CGContextAddArc(context, size.width-topRight, topRight, topRight-_borderTopWidth/2, -M_PI_4+(_borderRightWidth>0?0:M_PI_4), -M_PI_2, 1);
CGContextMoveToPoint(context, size.width-topRight, _borderTopWidth/2);
CGContextAddLineToPoint(context, topLeft, _borderTopWidth/2);
Expand All @@ -388,7 +390,7 @@ - (void)_drawBorderWithContext:(CGContextRef)context size:(CGSize)size
CGContextSetLineDash(context, 0, 0, 0);
}
CGContextSetLineWidth(context, _borderLeftWidth);
CGContextSetStrokeColorWithColor(context, _borderLeftColor.CGColor);
CGContextSetStrokeColorWithColor(context, [WXConvert UIColorFromRGBA:_borderLeftColor].CGColor);
CGContextAddArc(context, topLeft, topLeft, topLeft-_borderLeftWidth/2, -M_PI, -M_PI_2-M_PI_4+(_borderTopWidth > 0?0:M_PI_4), 0);
CGContextMoveToPoint(context, _borderLeftWidth/2, topLeft);
CGContextAddLineToPoint(context, _borderLeftWidth/2, size.height-bottomLeft);
Expand All @@ -409,7 +411,7 @@ - (void)_drawBorderWithContext:(CGContextRef)context size:(CGSize)size
CGContextSetLineDash(context, 0, 0, 0);
}
CGContextSetLineWidth(context, _borderBottomWidth);
CGContextSetStrokeColorWithColor(context, _borderBottomColor.CGColor);
CGContextSetStrokeColorWithColor(context, [WXConvert UIColorFromRGBA:_borderBottomColor].CGColor);
CGContextAddArc(context, bottomLeft, size.height-bottomLeft, bottomLeft-_borderBottomWidth/2, M_PI-M_PI_4+(_borderLeftWidth>0?0:M_PI_4), M_PI_2, 1);
CGContextMoveToPoint(context, bottomLeft, size.height-_borderBottomWidth/2);
CGContextAddLineToPoint(context, size.width-bottomRight, size.height-_borderBottomWidth/2);
Expand All @@ -430,7 +432,7 @@ - (void)_drawBorderWithContext:(CGContextRef)context size:(CGSize)size
CGContextSetLineDash(context, 0, 0, 0);
}
CGContextSetLineWidth(context, _borderRightWidth);
CGContextSetStrokeColorWithColor(context, _borderRightColor.CGColor);
CGContextSetStrokeColorWithColor(context, [WXConvert UIColorFromRGBA:_borderRightColor].CGColor);
CGContextAddArc(context, size.width-bottomRight, size.height-bottomRight, bottomRight-_borderRightWidth/2, M_PI_4+(_borderBottomWidth>0?0:M_PI_4), 0, 1);
CGContextMoveToPoint(context, size.width-_borderRightWidth/2, size.height-bottomRight);
CGContextAddLineToPoint(context, size.width-_borderRightWidth/2, topRight);
Expand Down Expand Up @@ -486,7 +488,7 @@ - (BOOL)_needsDrawBorder
if (!radiusEqual) {
return YES;
}
BOOL colorEqual = [_borderTopColor isEqual:_borderRightColor] && [_borderRightColor isEqual:_borderBottomColor] && [_borderBottomColor isEqual:_borderLeftColor];
BOOL colorEqual = _borderTopColor == _borderRightColor && _borderRightColor == _borderBottomColor && _borderBottomColor == _borderLeftColor;
if (!colorEqual) {
return YES;
}
Expand All @@ -499,7 +501,7 @@ - (void)_handleBorders:(NSDictionary *)styles isUpdating:(BOOL)updating
if (!updating) {
// init with default value
_borderTopStyle = _borderRightStyle = _borderBottomStyle = _borderLeftStyle = WXBorderStyleSolid;
_borderTopColor = _borderLeftColor = _borderRightColor = _borderBottomColor = [UIColor blackColor];
_borderTopColor = _borderLeftColor = _borderRightColor = _borderBottomColor = [WXConvert RGBAColorFromUIColor:[UIColor blackColor]];
_borderTopWidth = _borderLeftWidth = _borderRightWidth = _borderBottomWidth = 0;
_borderTopLeftRadius = _borderTopRightRadius = _borderBottomLeftRadius = _borderBottomRightRadius = 0;
}
Expand Down Expand Up @@ -541,6 +543,39 @@ - (void)_handleBorders:(NSDictionary *)styles isUpdating:(BOOL)updating
[self setNeedsDisplay];\
}\
} while (0);

#define WX_CHECK_BORDER_PROP_COLOR(prop, direction1, direction2, direction3, direction4, type)\
do {\
BOOL needsDisplay = NO; \
NSString *styleProp= WX_NSSTRING(WX_CONCAT(border, prop));\
if (styles[styleProp]) {\
_border##direction1##prop = _border##direction2##prop = _border##direction3##prop = _border##direction4##prop = [WXConvert RGBAColorFromUIColor:[WXConvert type:styles[styleProp]]];\
needsDisplay = YES;\
}\
NSString *styleDirection1Prop = WX_NSSTRING(WX_CONCAT_TRIPLE(border, direction1, prop));\
if (styles[styleDirection1Prop]) {\
_border##direction1##prop = [WXConvert RGBAColorFromUIColor:[WXConvert type:styles[styleDirection1Prop]]];\
needsDisplay = YES;\
}\
NSString *styleDirection2Prop = WX_NSSTRING(WX_CONCAT_TRIPLE(border, direction2, prop));\
if (styles[styleDirection2Prop]) {\
_border##direction2##prop = [WXConvert RGBAColorFromUIColor:[WXConvert type:styles[styleDirection2Prop]]];\
needsDisplay = YES;\
}\
NSString *styleDirection3Prop = WX_NSSTRING(WX_CONCAT_TRIPLE(border, direction3, prop));\
if (styles[styleDirection3Prop]) {\
_border##direction3##prop = [WXConvert RGBAColorFromUIColor:[WXConvert type:styles[styleDirection3Prop]]];\
needsDisplay = YES;\
}\
NSString *styleDirection4Prop = WX_NSSTRING(WX_CONCAT_TRIPLE(border, direction4, prop));\
if (styles[styleDirection4Prop]) {\
_border##direction4##prop = [WXConvert RGBAColorFromUIColor:[WXConvert type:styles[styleDirection4Prop]]];\
needsDisplay = YES;\
}\
if (needsDisplay && updating) {\
[self setNeedsDisplay];\
}\
} while (0);

// TODO: refactor this hopefully
#define WX_CHECK_BORDER_PROP_PIXEL(prop, direction1, direction2, direction3, direction4)\
Expand Down Expand Up @@ -578,7 +613,7 @@ - (void)_handleBorders:(NSDictionary *)styles isUpdating:(BOOL)updating


WX_CHECK_BORDER_PROP(Style, Top, Left, Bottom, Right, WXBorderStyle)
WX_CHECK_BORDER_PROP(Color, Top, Left, Bottom, Right, UIColor)
WX_CHECK_BORDER_PROP_COLOR(Color, Top, Left, Bottom, Right, UIColor)
WX_CHECK_BORDER_PROP_PIXEL(Width, Top, Left, Bottom, Right)
WX_CHECK_BORDER_PROP_PIXEL(Radius, TopLeft, TopRight, BottomLeft, BottomRight)

Expand All @@ -592,9 +627,9 @@ - (void)_handleBorders:(NSDictionary *)styles isUpdating:(BOOL)updating
} else if (!nowNeedsDrawBorder) {
[self _resetNativeBorderRadius];
_layer.borderWidth = _borderTopWidth;
_layer.borderColor = _borderTopColor.CGColor;
_layer.borderColor = [WXConvert UIColorFromRGBA:_borderTopColor].CGColor;
if ((_transition.transitionOptions & WXTransitionOptionsBackgroundColor) != WXTransitionOptionsBackgroundColor ) {
_layer.backgroundColor = _backgroundColor.CGColor;
_layer.backgroundColor = [WXConvert UIColorFromRGBA:_backgroundColor].CGColor;
}
}
}
Expand All @@ -606,7 +641,7 @@ - (BOOL)_bitmapOpaqueWithSize:(CGSize)size
WXRoundedRect *borderRect = [[WXRoundedRect alloc] initWithRect:rect topLeft:_borderTopLeftRadius topRight:_borderTopRightRadius bottomLeft:_borderBottomLeftRadius bottomRight:_borderBottomRightRadius];
WXRadii *radii = borderRect.radii;
BOOL hasBorderRadius = [radii hasBorderRadius];
return (!hasBorderRadius) && _opacity == 1.0 && CGColorGetAlpha(_backgroundColor.CGColor) == 1.0 && [self _needsDrawBorder];
return (!hasBorderRadius) && _opacity == 1.0 && CGColorGetAlpha([WXConvert UIColorFromRGBA:_backgroundColor].CGColor) == 1.0 && [self _needsDrawBorder];
}

- (CAShapeLayer *)drawBorderRadiusMaskLayer:(CGRect)rect
Expand Down
9 changes: 1 addition & 8 deletions ios/sdk/WeexSDK/Sources/Loader/WXResourceLoader.m
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,7 @@ - (void)request:(WXResourceRequest *)request didReceiveResponse:(WXResourceRespo
WXLogDebug(@"request:%@ didReceiveResponse:%@ ", request, response);

_response = response;
id<WXConfigCenterProtocol> configCenter = [WXSDKEngine handlerForProtocol:@protocol(WXConfigCenterProtocol)];
if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) {
BOOL isDefault;
BOOL clearResponseData = [[configCenter configForKey:@"iOS_weex_ext_config.clearResponseDataWhenDidReceiveResponse" defaultValue:@(NO) isDefault:&isDefault] boolValue];
if(clearResponseData) {
_data = nil;
}
}
_data = nil;

if (self.onResponseReceived) {
self.onResponseReceived(response);
Expand Down
9 changes: 5 additions & 4 deletions ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,11 @@ - (UIView *)view
_view.hidden = _visibility == WXVisibilityShow ? NO : YES;
_view.clipsToBounds = _clipToBounds;
if (![self _needsDrawBorder]) {
_layer.borderColor = _borderTopColor.CGColor;
_layer.borderColor = [WXConvert UIColorFromRGBA:_borderTopColor].CGColor;
_layer.borderWidth = _borderTopWidth;
[self _resetNativeBorderRadius];
_layer.opacity = _opacity;
_view.backgroundColor = _backgroundColor;
_view.backgroundColor = [WXConvert UIColorFromRGBA:_backgroundColor];
}

if (_backgroundImage) {
Expand Down Expand Up @@ -857,8 +857,9 @@ - (void)setGradientLayer
UIColor * endColor = (UIColor*)linearGradient[@"endColor"];
CAGradientLayer * gradientLayer = [WXUtility gradientLayerFromColors:@[startColor, endColor] locations:nil frame:strongSelf.view.bounds gradientType:(WXGradientType)[linearGradient[@"gradientType"] integerValue]];
if (gradientLayer) {
_backgroundColor = [UIColor colorWithPatternImage:[strongSelf imageFromLayer:gradientLayer]];
strongSelf.view.backgroundColor = _backgroundColor;
UIColor* patternColor = [UIColor colorWithPatternImage:[strongSelf imageFromLayer:gradientLayer]];
_backgroundColor = [WXConvert RGBAColorFromUIColor:patternColor];
strongSelf.view.backgroundColor = patternColor;
[strongSelf setNeedsDisplay];
}
}
Expand Down
2 changes: 2 additions & 0 deletions ios/sdk/WeexSDK/Sources/Utility/WXConvert.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ typedef CGFloat WXPixelType;
+ (UIAccessibilityTraits)WXUIAccessibilityTraits:(id)value;

+ (UIColor *)UIColor:(id)value;
+ (UIColor *)UIColorFromRGBA:(uint32_t)rgba;
+ (uint32_t)RGBAColorFromUIColor:(UIColor*)color;
+ (CGColorRef)CGColor:(id)value;
+ (NSString *)HexWithColor:(UIColor *)color;
+ (WXBorderStyle)WXBorderStyle:(id)value;
Expand Down
30 changes: 30 additions & 0 deletions ios/sdk/WeexSDK/Sources/Utility/WXConvert.m
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,36 @@ + (UIColor *)UIColor:(id)value
return color;
}

+ (UIColor *)UIColorFromRGBA:(uint32_t)rgba
{
float r, g, b, a;
uint8_t r8, g8, b8, a8;
r8 = rgba >> 24;
g8 = (rgba & 0x00FF0000) >> 16;
b8 = (rgba & 0x0000FF00) >> 8;
a8 = rgba & 0x000000FF;
r = r8 / 255.f;
g = g8 / 255.f;
b = b8 / 255.f;
a = a8 / 255.f;
return [UIColor colorWithRed:r green:g blue:b alpha:a];
}

+ (uint32_t)RGBAColorFromUIColor:(UIColor*)color
{
CGFloat r, g, b, a;
if (color) {
[color getRed:&r green:&g blue:&b alpha:&a];
uint8_t r8, g8, b8, a8;
r8 = (uint8_t)(lround(r * 255.f));
g8 = (uint8_t)(lround(g * 255.f));
b8 = (uint8_t)(lround(b * 255.f));
a8 = (uint8_t)(lround(a * 255.f));
return ((uint32_t)r8 << 24) | ((uint32_t)g8 << 16) | ((uint32_t)b8 << 8) | (uint32_t)a8;
}
return 0;
}

+ (CGColorRef)CGColor:(id)value
{
UIColor *color = [self UIColor:value];
Expand Down
13 changes: 7 additions & 6 deletions ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.mm
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@
#define WX_BOARD_RADIUS_COLOR_RESET_ALL(key)\
do {\
if (styles && [styles containsObject:@#key]) {\
_borderTopColor = _borderLeftColor = _borderRightColor = _borderBottomColor = [UIColor blackColor];\
_borderTopColor = _borderLeftColor = _borderRightColor = _borderBottomColor = [WXConvert RGBAColorFromUIColor:[UIColor blackColor]];\
[self setNeedsDisplay];\
}\
} while(0);

#define WX_BOARD_COLOR_RESET(key)\
do {\
if (styles && [styles containsObject:@#key]) {\
_##key = [UIColor blackColor];\
_##key = [WXConvert RGBAColorFromUIColor:[UIColor blackColor]];\
[self setNeedsDisplay];\
}\
} while(0);
Expand Down Expand Up @@ -174,7 +174,8 @@ - (void)viewDidUnload

- (void)_initViewPropertyWithStyles:(NSDictionary *)styles
{
_backgroundColor = styles[@"backgroundColor"] ? [WXConvert UIColor:styles[@"backgroundColor"]] : [UIColor clearColor];
UIColor* bgColor = styles[@"backgroundColor"] ? [WXConvert UIColor:styles[@"backgroundColor"]] : [UIColor clearColor];
_backgroundColor = [WXConvert RGBAColorFromUIColor:bgColor ?: [UIColor clearColor]];
_backgroundImage = styles[@"backgroundImage"] ? [WXConvert NSString:styles[@"backgroundImage"]]: nil;
_opacity = styles[@"opacity"] ? [WXConvert CGFloat:styles[@"opacity"]] : 1.0;
_clipToBounds = styles[@"overflow"] ? [WXConvert WXClipType:styles[@"overflow"]] : NO;
Expand All @@ -193,7 +194,7 @@ - (void)_transitionUpdateViewProperty:(NSDictionary *)styles
{
WX_CHECK_COMPONENT_TYPE(self.componentType)
if (styles[@"backgroundColor"]) {
_backgroundColor = [WXConvert UIColor:styles[@"backgroundColor"]];
_backgroundColor = [WXConvert RGBAColorFromUIColor:[WXConvert UIColor:styles[@"backgroundColor"]]];
}
if (styles[@"opacity"]) {
_opacity = [WXConvert CGFloat:styles[@"opacity"]];
Expand All @@ -211,7 +212,7 @@ - (void)_updateViewStyles:(NSDictionary *)styles
}

if (styles[@"backgroundColor"]) {
_backgroundColor = [WXConvert UIColor:styles[@"backgroundColor"]];
_backgroundColor = [WXConvert RGBAColorFromUIColor:[WXConvert UIColor:styles[@"backgroundColor"]]];
[self setNeedsDisplay];
}

Expand Down Expand Up @@ -307,7 +308,7 @@ - (void)resetBorder:(NSArray *)styles
- (void)_resetStyles:(NSArray *)styles
{
if (styles && [styles containsObject:@"backgroundColor"]) {
_backgroundColor = [UIColor clearColor];
_backgroundColor = [WXConvert RGBAColorFromUIColor:[UIColor clearColor]];
[self setNeedsDisplay];
}
if (styles && [styles containsObject:@"boxShadow"]) {
Expand Down