From cfae3e376d96653e5ad48e0d0398674a954d3637 Mon Sep 17 00:00:00 2001 From: Martin Kralik Date: Tue, 27 Sep 2016 03:36:32 -0700 Subject: [PATCH] fixed crash when setting custom shadow props to null Reviewed By: emilsjolander Differential Revision: D3923634 fbshipit-source-id: 005e316e70fa280960c796375b2e94f9967a089d --- React/Views/RCTComponentData.m | 28 ++++++++++++++++++++-------- React/Views/RCTViewManager.h | 4 ++-- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/React/Views/RCTComponentData.m b/React/Views/RCTComponentData.m index 9d1881505..b0d61fe86 100644 --- a/React/Views/RCTComponentData.m +++ b/React/Views/RCTComponentData.m @@ -145,8 +145,14 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) // Check for custom setter if ([keyPath isEqualToString:@"__custom__"]) { - // Get custom setter - SEL customSetter = NSSelectorFromString([NSString stringWithFormat:@"set_%@:for%@View:withDefaultView:", name, shadowView ? @"Shadow" : @""]); + // Get custom setter. There is no default view in the shadow case, so the selector is different. + NSString *selectorString; + if (!shadowView) { + selectorString = [NSString stringWithFormat:@"set_%@:for%@View:withDefaultView:", name, shadowView ? @"Shadow" : @""]; + } else { + selectorString = [NSString stringWithFormat:@"set_%@:forShadowView:", name]; + } + SEL customSetter = NSSelectorFromString(selectorString); propBlock = ^(id view, id json) { RCTComponentData *strongSelf = weakSelf; @@ -154,13 +160,19 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) return; } json = RCTNilIfNull(json); - if (!json && !strongSelf->_defaultView) { - // Only create default view if json is null - strongSelf->_defaultView = [strongSelf createViewWithTag:nil]; + if (!shadowView) { + if (!json && !strongSelf->_defaultView) { + // Only create default view if json is null + strongSelf->_defaultView = [strongSelf createViewWithTag:nil]; + } + ((void (*)(id, SEL, id, id, id))objc_msgSend)( + strongSelf.manager, customSetter, json, view, strongSelf->_defaultView + ); + } else { + ((void (*)(id, SEL, id, id))objc_msgSend)( + strongSelf.manager, customSetter, json, view + ); } - ((void (*)(id, SEL, id, id, id))objc_msgSend)( - strongSelf.manager, customSetter, json, view, strongSelf->_defaultView - ); }; } else { diff --git a/React/Views/RCTViewManager.h b/React/Views/RCTViewManager.h index 14bb93964..568cd867b 100644 --- a/React/Views/RCTViewManager.h +++ b/React/Views/RCTViewManager.h @@ -126,10 +126,10 @@ RCT_REMAP_VIEW_PROPERTY(name, __custom__, type) \ /** * This macro can be used when you need to provide custom logic for setting * shadow view properties. The macro should be followed by a method body, which can - * refer to "json", "view" and "defaultView" to implement the required logic. + * refer to "json" and "view". */ #define RCT_CUSTOM_SHADOW_PROPERTY(name, type, viewClass) \ RCT_REMAP_SHADOW_PROPERTY(name, __custom__, type) \ -- (void)set_##name:(id)json forShadowView:(viewClass *)view withDefaultView:(viewClass *)defaultView +- (void)set_##name:(id)json forShadowView:(viewClass *)view @end