mirror of
https://github.com/status-im/react-native.git
synced 2025-02-04 05:34:15 +00:00
Fabric: Support for view recycling in RCTComponentViewRegistry
Summary: Quite trivial but still very cool recycling of native view instances is finnally here, in React Native. � Reviewed By: mdvacca Differential Revision: D7804085 fbshipit-source-id: 644804da3185f9ed3fdea42d4d76c93e86934448
This commit is contained in:
parent
6e537b000b
commit
7cf7028092
@ -10,8 +10,11 @@
|
||||
#import <Foundation/NSMapTable.h>
|
||||
#import <React/RCTAssert.h>
|
||||
|
||||
const NSInteger RCTComponentViewRegistryRecyclePoolMaxSize = 256;
|
||||
|
||||
@implementation RCTComponentViewRegistry {
|
||||
NSMapTable<id, UIView<RCTComponentViewProtocol> *> *_registry;
|
||||
NSMapTable<NSString *, NSHashTable<UIView<RCTComponentViewProtocol> *> *> *_recyclePool;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
@ -19,6 +22,8 @@
|
||||
if (self = [super init]) {
|
||||
_registry = [NSMapTable mapTableWithKeyOptions:NSPointerFunctionsIntegerPersonality | NSPointerFunctionsOpaqueMemory
|
||||
valueOptions:NSPointerFunctionsObjectPersonality];
|
||||
_recyclePool = [NSMapTable mapTableWithKeyOptions:NSPointerFunctionsObjectPersonality
|
||||
valueOptions:NSPointerFunctionsObjectPersonality];
|
||||
}
|
||||
|
||||
return self;
|
||||
@ -28,9 +33,8 @@
|
||||
tag:(ReactTag)tag
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
// This is temporary approach.
|
||||
NSString *className = [NSString stringWithFormat:@"RCT%@ComponentView", componentName];
|
||||
UIView<RCTComponentViewProtocol> *componentView = [[NSClassFromString(className) alloc] init];
|
||||
UIView<RCTComponentViewProtocol> *componentView =
|
||||
[self _dequeueComponentViewWithName:componentName];
|
||||
componentView.tag = tag;
|
||||
[_registry setObject:componentView forKey:(__bridge id)(void *)tag];
|
||||
return componentView;
|
||||
@ -42,6 +46,8 @@
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
[_registry removeObjectForKey:(__bridge id)(void *)tag];
|
||||
componentView.tag = 0;
|
||||
[self _enqueueComponentViewWithName:componentName componentView:componentView];
|
||||
}
|
||||
|
||||
- (UIView<RCTComponentViewProtocol> *)componentViewByTag:(ReactTag)tag
|
||||
@ -56,4 +62,45 @@
|
||||
return componentView.tag;
|
||||
}
|
||||
|
||||
- (UIView<RCTComponentViewProtocol> *)_createComponentViewWithName:(NSString *)componentName
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
// This is temporary approach.
|
||||
NSString *className = [NSString stringWithFormat:@"RCT%@ComponentView", componentName];
|
||||
UIView<RCTComponentViewProtocol> *componentView = [[NSClassFromString(className) alloc] init];
|
||||
return componentView;
|
||||
}
|
||||
|
||||
- (nullable UIView<RCTComponentViewProtocol> *)_dequeueComponentViewWithName:(NSString *)componentName
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
NSHashTable<UIView<RCTComponentViewProtocol> *> *componentViews = [_recyclePool objectForKey:componentName];
|
||||
if (!componentViews || componentViews.count == 0) {
|
||||
return [self _createComponentViewWithName:componentName];
|
||||
}
|
||||
|
||||
UIView<RCTComponentViewProtocol> *componentView = [componentViews anyObject];
|
||||
[componentViews removeObject:componentView];
|
||||
return componentView;
|
||||
}
|
||||
|
||||
- (void)_enqueueComponentViewWithName:(NSString *)componentName
|
||||
componentView:(UIView<RCTComponentViewProtocol> *)componentView
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
[componentView prepareForRecycle];
|
||||
|
||||
NSHashTable<UIView<RCTComponentViewProtocol> *> *componentViews = [_recyclePool objectForKey:componentName];
|
||||
if (!componentViews) {
|
||||
componentViews = [NSHashTable hashTableWithOptions:NSPointerFunctionsObjectPersonality];
|
||||
[_recyclePool setObject:componentViews forKey:componentName];
|
||||
}
|
||||
|
||||
if (componentViews.count >= RCTComponentViewRegistryRecyclePoolMaxSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
[componentViews addObject:componentView];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -10,6 +10,7 @@
|
||||
#import <React/RCTComponentViewProtocol.h>
|
||||
#import <React/UIView+ComponentViewProtocol.h>
|
||||
#import <fabric/core/LayoutMetrics.h>
|
||||
#import <fabric/core/Props.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@ -19,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@interface RCTViewComponentView : UIView <RCTComponentViewProtocol> {
|
||||
@protected
|
||||
facebook::react::LayoutMetrics _layoutMetrics;
|
||||
facebook::react::SharedProps _props;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -17,8 +17,9 @@ using namespace facebook::react;
|
||||
oldProps:(facebook::react::SharedProps)oldProps
|
||||
{
|
||||
if (!oldProps) {
|
||||
oldProps = std::make_shared<ViewProps>();
|
||||
oldProps = _props ?: std::make_shared<ViewProps>();
|
||||
}
|
||||
_props = props;
|
||||
|
||||
auto oldViewProps = *std::dynamic_pointer_cast<const ViewProps>(oldProps);
|
||||
auto newViewProps = *std::dynamic_pointer_cast<const ViewProps>(props);
|
||||
|
Loading…
x
Reference in New Issue
Block a user