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

Commit

Permalink
Merge 0927 bugfixes (#1585)
Browse files Browse the repository at this point in the history
* [iOS]Crash fix

* [iOS] fix transition may cause memory leak.

* [iOS] Refactor. Fix move element. No need to calculate index and do not destroy render object.

* [iOS] Fix transition.

* [iOS] Change log string.

* [Core] Refactor. Change to ObjC method.

* [iOS] Add switch for create instance optimization.

* [Core] Refactor. Mask component height fix on iOS.

* [Core] Refactor. Mask component height fix on iOS. Add comment.
  • Loading branch information
wqyfavor authored and cxfeng1 committed Sep 26, 2018
1 parent 4652d7f commit 23f9a20
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 112 deletions.
85 changes: 50 additions & 35 deletions ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
Original file line number Diff line number Diff line change
Expand Up @@ -467,50 +467,65 @@ - (void)createInstance:(NSString *)instanceIdString
}
}

JSContextRef contextRef = instanceContextEnvironment.context.JSGlobalContextRef;
WXAssert([instanceContextEnvironment isObject], @"Invalid instance context.");
JSObjectRef instanceContextObjectRef = JSValueToObject(contextRef, instanceContextEnvironment.JSValueRef, NULL);
JSPropertyNameArrayRef allKeyRefs = JSObjectCopyPropertyNames(contextRef, instanceContextObjectRef);
size_t keyCount = JSPropertyNameArrayGetCount(allKeyRefs);
NSMutableArray* allKeys = nil;

BOOL somethingWrong = NO;
NSMutableArray* allKeys = [[NSMutableArray alloc] initWithCapacity:keyCount];
for (size_t i = 0; i < keyCount; i ++) {
JSStringRef nameRef = JSPropertyNameArrayGetNameAtIndex(allKeyRefs, i);
size_t len = JSStringGetMaximumUTF8CStringSize(nameRef);
if (len > 1024) {
somethingWrong = YES;
break;
}
char* buf = (char*)malloc(len + 5);
if (buf == NULL) {
somethingWrong = YES;
break;
if ([WXUtility useJSCApiForCreateInstance]) {
JSContextRef contextRef = instanceContextEnvironment.context.JSGlobalContextRef;
WXAssert([instanceContextEnvironment isObject], @"Invalid instance context.");
JSValueRef jsException = NULL;
JSObjectRef instanceContextObjectRef = JSValueToObject(contextRef, instanceContextEnvironment.JSValueRef, &jsException);
if (jsException != NULL) {
WXLogError(@"JSValueToObject Exception during create instance.");
}
bzero(buf, len + 5);
if (JSStringGetUTF8CString(nameRef, buf, len + 5) > 0) {
NSString* keyString = [NSString stringWithUTF8String:buf];
if ([keyString length] == 0) {
somethingWrong = YES;
BOOL somethingWrong = NO;
if (instanceContextObjectRef != NULL) {
JSPropertyNameArrayRef allKeyRefs = JSObjectCopyPropertyNames(contextRef, instanceContextObjectRef);
size_t keyCount = JSPropertyNameArrayGetCount(allKeyRefs);

allKeys = [[NSMutableArray alloc] initWithCapacity:keyCount];
for (size_t i = 0; i < keyCount; i ++) {
JSStringRef nameRef = JSPropertyNameArrayGetNameAtIndex(allKeyRefs, i);
size_t len = JSStringGetMaximumUTF8CStringSize(nameRef);
if (len > 1024) {
somethingWrong = YES;
break;
}
char* buf = (char*)malloc(len + 5);
if (buf == NULL) {
somethingWrong = YES;
break;
}
bzero(buf, len + 5);
if (JSStringGetUTF8CString(nameRef, buf, len + 5) > 0) {
NSString* keyString = [NSString stringWithUTF8String:buf];
if ([keyString length] == 0) {
somethingWrong = YES;
free(buf);
break;
}
[allKeys addObject:keyString];
}
else {
somethingWrong = YES;
free(buf);
break;
}
free(buf);
break;
}
[allKeys addObject:keyString];
}
else {
JSPropertyNameArrayRelease(allKeyRefs);
} else {
somethingWrong = YES;
free(buf);
break;
}
free(buf);

if (somethingWrong) {
// [instanceContextEnvironment toDictionary] may contain retain-cycle.
allKeys = (NSMutableArray*)[[instanceContextEnvironment toDictionary] allKeys];
}
}
JSPropertyNameArrayRelease(allKeyRefs);

if (somethingWrong) {
// [instanceContextEnvironment toDictionary] may contain retain-cycle.
else {
allKeys = (NSMutableArray*)[[instanceContextEnvironment toDictionary] allKeys];
}

sdkInstance.createInstanceContextResult = [NSString stringWithFormat:@"%@", allKeys];
JSGlobalContextRef instanceContextRef = sdkInstance.instanceJavaScriptContext.javaScriptContext.JSGlobalContextRef;
JSObjectRef instanceGlobalObject = JSContextGetGlobalObject(instanceContextRef);
Expand Down
69 changes: 15 additions & 54 deletions ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ + (void)closePage:(NSString*)pageId
}
}

static void _traverseTree(WeexCore::RenderObject *render, int index, const char* pageId)
+ (void)_traverseTree:(WeexCore::RenderObject *)render index:(int)index pageId:(const char *)pageId
{
using namespace WeexCore;
if (render == nullptr) return;
Expand Down Expand Up @@ -944,7 +944,7 @@ static void _traverseTree(WeexCore::RenderObject *render, int index, const char*
for (auto it = render->ChildListIterBegin(); it != render->ChildListIterEnd(); it ++) {
WeexCore::RenderObject *child = static_cast<WeexCore::RenderObject *>(*it);
if (child != nullptr) {
_traverseTree(child, (int)(it - render->ChildListIterBegin()), pageId);
[self _traverseTree:child index:(int)(it - render->ChildListIterBegin()) pageId:pageId];
}
}
}
Expand All @@ -956,7 +956,7 @@ + (void)layoutRenderObject:(void*)object size:(CGSize)size page:(NSString*)pageI
std::pair<float, float> renderPageSize(size.width, size.height);

render->calculateLayout(renderPageSize);
_traverseTree(render, 0, [pageId UTF8String] ?: "");
[self _traverseTree:render index:0 pageId:[pageId UTF8String] ?: ""];
}

+ (void*)copyRenderObject:(void*)source replacedRef:(NSString*)ref
Expand Down Expand Up @@ -999,45 +999,7 @@ static void _convertToCString(id _Nonnull obj, void (^callback)(const char*))
callback([obj UTF8String]);
}
else if ([obj isKindOfClass:[NSNumber class]]) {
NSNumber* num = (NSNumber*)obj;
char objcType = [num objCType][0];
char buffer[128];
switch (objcType) {
case _C_DBL:
case _C_FLT:
snprintf(buffer, sizeof(buffer), "%f", [num doubleValue]);
callback(buffer);
break;
case _C_INT:
case _C_CHR:
case _C_SHT:
snprintf(buffer, sizeof(buffer), "%d", [num intValue]);
callback(buffer);
break;
case _C_USHT:
case _C_UINT:
case _C_UCHR:
snprintf(buffer, sizeof(buffer), "%u", [num unsignedIntValue]);
callback(buffer);
break;
case _C_LNG:
case _C_LNG_LNG:
snprintf(buffer, sizeof(buffer), "%lld", [num longLongValue]);
callback(buffer);
break;
case _C_ULNG:
case _C_ULNG_LNG:
snprintf(buffer, sizeof(buffer), "%llu", [num unsignedLongLongValue]);
callback(buffer);
break;
case _C_BFLD:
case _C_BOOL:
callback([num boolValue] ? "true" : "false");
break;
default:
callback([[num stringValue] UTF8String]);
break;
}
callback([[(NSNumber*)obj stringValue] UTF8String]);
}
else if ([obj isKindOfClass:[NSNull class]]) {
callback([JSONSTRING_SUFFIX UTF8String]);
Expand All @@ -1050,7 +1012,7 @@ static void _convertToCString(id _Nonnull obj, void (^callback)(const char*))
}
}

static void _parseStyleBeforehand(NSDictionary* styles, NSString* key, WeexCore::RenderObject* render)
+ (void)_parseStyleBeforehand:(NSDictionary *)styles key:(NSString *)key render:(WeexCore::RenderObject*)render
{
id data = styles[key];
if (data) {
Expand All @@ -1062,8 +1024,7 @@ static void _parseStyleBeforehand(NSDictionary* styles, NSString* key, WeexCore:
}
}

static WeexCore::RenderObject* _parseRenderObject(NSDictionary* data, WeexCore::RenderObject* parent,
int index, const std::string& pageId)
+ (WeexCore::RenderObject*)_parseRenderObject:(NSDictionary *)data parent:(WeexCore::RenderObject *)parent index:(int)index pageId:(const std::string&)pageId
{
using namespace WeexCore;

Expand All @@ -1086,9 +1047,9 @@ static void _parseStyleBeforehand(NSDictionary* styles, NSString* key, WeexCore:

// margin/padding/borderWidth should be handled beforehand. Because maringLeft should override margin.
NSDictionary* styles = data[@"style"];
_parseStyleBeforehand(styles, @"margin", render);
_parseStyleBeforehand(styles, @"padding", render);
_parseStyleBeforehand(styles, @"borderWidth", render);
[self _parseStyleBeforehand:styles key:@"margin" render:render];
[self _parseStyleBeforehand:styles key:@"padding" render:render];
[self _parseStyleBeforehand:styles key:@"borderWidth" render:render];
[styles enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
if ([key isEqualToString:@"margin"] || [key isEqualToString:@"padding"] || [key isEqualToString:@"borderWidth"]) {
return;
Expand All @@ -1110,7 +1071,7 @@ static void _parseStyleBeforehand(NSDictionary* styles, NSString* key, WeexCore:

int childIndex = 0;
for (NSDictionary* obj in data[@"children"]) {
_parseRenderObject(obj, render, childIndex ++, pageId);
[self _parseRenderObject:obj parent:render index:childIndex ++ pageId:pageId];
}

render->ApplyDefaultStyle();
Expand All @@ -1121,7 +1082,7 @@ static void _parseStyleBeforehand(NSDictionary* styles, NSString* key, WeexCore:
return nullptr;
}

static std::vector<std::pair<std::string, std::string>>* _parseMapValuePairs(NSDictionary* data)
+ (std::vector<std::pair<std::string, std::string>>*)_parseMapValuePairs:(NSDictionary *)data
{
std::vector<std::pair<std::string, std::string>>* result = new std::vector<std::pair<std::string, std::string>>();
[data enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
Expand All @@ -1138,7 +1099,7 @@ + (void)callAddElement:(NSString*)pageId parentRef:(NSString*)parentRef data:(NS
{
using namespace WeexCore;
const std::string page([pageId UTF8String] ?: "");
RenderObject* child = _parseRenderObject(data, nullptr, 0, page);
RenderObject* child = [self _parseRenderObject:data parent:nullptr index:0 pageId:page];
RenderManager::GetInstance()->AddRenderObject(page, [parentRef UTF8String] ?: "", index, child);
}

Expand All @@ -1150,7 +1111,7 @@ + (void)callCreateBody:(NSString*)pageId data:(NSDictionary*)data
pageInstance->set_before_layout_needed(false); // we do not need before and after layout
pageInstance->set_after_layout_needed(false);
pageInstance->set_platform_layout_needed(true);
return _parseRenderObject(data, nullptr, 0, page);
return [self _parseRenderObject:data parent:nullptr index:0 pageId:page];
});
}

Expand All @@ -1166,12 +1127,12 @@ + (void)callMoveElement:(NSString*)pageId ref:(NSString*)ref parentRef:(NSString

+ (void)callUpdateAttrs:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*)data
{
WeexCore::RenderManager::GetInstance()->UpdateAttr([pageId UTF8String] ?: "", [ref UTF8String] ?: "", _parseMapValuePairs(data));
WeexCore::RenderManager::GetInstance()->UpdateAttr([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [self _parseMapValuePairs:data]);
}

+ (void)callUpdateStyle:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*)data
{
WeexCore::RenderManager::GetInstance()->UpdateStyle([pageId UTF8String] ?: "", [ref UTF8String] ?: "", _parseMapValuePairs(data));
WeexCore::RenderManager::GetInstance()->UpdateStyle([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [self _parseMapValuePairs:data]);
}

+ (void)callAddEvent:(NSString*)pageId ref:(NSString*)ref event:(NSString*)event
Expand Down
2 changes: 1 addition & 1 deletion ios/sdk/WeexSDK/Sources/Component/WXCellComponent.mm
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ - (void)_moveToSupercomponent:(WXComponent *)newSupercomponent atIndex:(NSUInteg
{
if (self.delegate == (id<WXCellRenderDelegate>)newSupercomponent) {
[self.delegate cell:self didMoveToIndex:index];
[super _removeFromSupercomponent];
[super _removeFromSupercomponent:NO]; // no remove underlayer render object
[newSupercomponent _insertSubcomponent:self atIndex:index];
} else {
[super _moveToSupercomponent:newSupercomponent atIndex:index];
Expand Down
1 change: 1 addition & 0 deletions ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ typedef id (^WXDataBindingBlock)(NSDictionary *data, BOOL *needUpdate);
- (BOOL)_insertSubcomponent:(WXComponent *)subcomponent atIndex:(NSInteger)index;

- (void)_removeFromSupercomponent;
- (void)_removeFromSupercomponent:(BOOL)remove;
- (void)_moveToSupercomponent:(WXComponent *)newSupercomponent atIndex:(NSUInteger)index;

- (BOOL)_isTransitionNone;
Expand Down
6 changes: 0 additions & 6 deletions ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -328,12 +328,6 @@ - (void)moveComponent:(NSString *)ref toSuper:(NSString *)superRef atIndex:(NSIn
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:^{
Expand Down
21 changes: 14 additions & 7 deletions ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
Original file line number Diff line number Diff line change
Expand Up @@ -606,31 +606,38 @@ - (BOOL)_insertSubcomponent:(WXComponent *)subcomponent atIndex:(NSInteger)index
return YES;
}

- (void)_removeSubcomponent:(WXComponent *)subcomponent
- (void)_removeSubcomponent:(WXComponent *)subcomponent removeCssNode:(BOOL)removeCssNode
{
pthread_mutex_lock(&_propertyMutex);
[_subcomponents removeObject:subcomponent];
[self removeSubcomponentCssNode:subcomponent];
if (removeCssNode) {
[self removeSubcomponentCssNode:subcomponent];
}
pthread_mutex_unlock(&_propertyMutex);
}

- (void)_removeFromSupercomponent
{
[self.supercomponent _removeSubcomponent:self];
[self _removeFromSupercomponent:YES]; // really do remove
}

- (void)_removeFromSupercomponent:(BOOL)remove
{
[self.supercomponent _removeSubcomponent:self removeCssNode:remove];
[self.supercomponent setNeedsLayout];

if (_positionType == WXPositionTypeFixed) {
[self.weexInstance.componentManager removeFixedComponent:self];
self->_isNeedJoinLayoutSystem = YES;
}
if (_positionType == WXPositionTypeSticky) {
[self.ancestorScroller removeStickyComponent:self];
}
if (_positionType == WXPositionTypeSticky) {
[self.ancestorScroller removeStickyComponent:self];
}
}

- (void)_moveToSupercomponent:(WXComponent *)newSupercomponent atIndex:(NSUInteger)index
{
[self _removeFromSupercomponent];
[self _removeFromSupercomponent:NO]; // no remove underlayer render object
[newSupercomponent _insertSubcomponent:self atIndex:index];
}

Expand Down
3 changes: 3 additions & 0 deletions ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,9 @@ - (BOOL)_handleConfigCenter

BOOL listSectionRowThreadSafe = [[configCenter configForKey:@"iOS_weex_ext_config.listSectionRowThreadSafe" defaultValue:@(YES) isDefault:NULL] boolValue];
[WXUtility setListSectionRowThreadSafe:listSectionRowThreadSafe];

BOOL useJSCApiForCreateInstance = [[configCenter configForKey:@"iOS_weex_ext_config.useJSCApiForCreateInstance" defaultValue:@(YES) isDefault:NULL] boolValue];
[WXUtility setUseJSCApiForCreateInstance:useJSCApiForCreateInstance];

//Reading config from orange for Release instance in Main Thread or not
_bReleaseInstanceInMainThread = [[configCenter configForKey:@"iOS_weex_ext_config.releaseInstanceInMainThread" defaultValue:@(YES) isDefault:nil] boolValue];
Expand Down
8 changes: 4 additions & 4 deletions ios/sdk/WeexSDK/Sources/Module/WXTransition.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ typedef NS_OPTIONS(NSUInteger, WXTransitionOptions) {
@end

@interface WXTransition : NSObject
@property(nonatomic,strong) NSMutableDictionary *oldFilterStyles;
@property(nonatomic,strong) NSMutableDictionary *filterStyles;
@property(nonatomic,strong) NSMutableArray *propertyArray;
@property(nonatomic,assign) WXTransitionOptions transitionOptions;
@property (nonatomic,strong) NSMutableDictionary *oldFilterStyles;
@property (nonatomic,strong) NSMutableDictionary *filterStyles;
@property (nonatomic,strong) NSMutableArray *propertyArray;
@property (nonatomic,assign) WXTransitionOptions transitionOptions;
- (instancetype) initWithStyles:(NSDictionary *)styles;
- (void)_handleTransitionWithStyles:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles target:(WXComponent *)targetComponent;
- (BOOL)_hasTransitionOptionInStyles:(NSDictionary *)styles;
Expand Down
Loading

0 comments on commit 23f9a20

Please sign in to comment.