Introducing RCTWeakViewHolder [4/n]

Summary:
Problem: In paper, there is a handy API called `[uiManager viewForReactTag:]`. Fabric does not have this mapping. The Fabric interop layer still relies on this Paper mapping.

Solution: As a workaround, re-create this mapping in the Fabric interop layer. Therefore, whenever Fabric interop layer asks a paper view manager to create a view, store a weak reference to the view in a `NSMapTable`. NSMapTable allows us to customize the strong/weak relationship. I've added a comment explaining that `RCTWeakViewHolder` only needs to be used for this special circumstance.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D27438899

fbshipit-source-id: 94663ef06479a8c863ce58b0f36d42109fa1c4f3
This commit is contained in:
Peter Argany
2021-03-31 16:39:02 -07:00
committed by Facebook GitHub Bot
parent 10acccc86d
commit 4efdf264d1
4 changed files with 32 additions and 7 deletions
@@ -31,9 +31,7 @@
- (UIView *)paperView
{
if (!_paperView) {
_paperView = _coordinator.paperView;
_paperView.reactTag = [NSNumber numberWithInteger:_tag];
_paperView = [_coordinator createPaperViewWithTag:_tag];
__weak __typeof(self) weakSelf = self;
[_coordinator addObserveForTag:_tag
usingBlock:^(std::string eventName, folly::dynamic event) {
+19
View File
@@ -0,0 +1,19 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/*
* THIS IS A HACK
* This protocol should only be used for Paper ViewManagers which need to
* use the Fabric Interop layer, and also need to reference their created
* views. This protocol allows the view manager to store a weak reference to
* any created views. It will not affect view lifecycle in any way.
*/
@protocol RCTWeakViewHolder
@property (nonatomic, strong) NSMapTable<NSNumber *, UIView *> *weakViews;
@end
@@ -20,7 +20,7 @@ typedef void (^InterceptorBlock)(std::string eventName, folly::dynamic event);
- (instancetype)initWithComponentData:(RCTComponentData *)componentData bridge:(RCTBridge *)bridge;
- (UIView *)paperView;
- (UIView *)createPaperViewWithTag:(NSInteger)tag;
- (void)addObserveForTag:(NSInteger)tag usingBlock:(InterceptorBlock)block;
@@ -16,6 +16,7 @@
#include <React/RCTUIManager.h>
#include <React/RCTUIManagerUtils.h>
#include <React/RCTUtils.h>
#include <React/RCTWeakViewHolder.h>
#include <folly/json.h>
#include <objc/runtime.h>
@@ -70,10 +71,17 @@ using namespace facebook::react;
[_eventInterceptors removeObjectForKey:[NSNumber numberWithInteger:tag]];
}
- (UIView *)paperView
- (UIView *)createPaperViewWithTag:(NSInteger)tag;
{
// TODO: pass in the right tags?
return [_componentData createViewWithTag:NULL rootTag:NULL];
UIView *view = [_componentData createViewWithTag:[NSNumber numberWithInteger:tag] rootTag:NULL];
if ([_componentData.bridgelessViewManager conformsToProtocol:@protocol(RCTWeakViewHolder)]) {
id<RCTWeakViewHolder> weakViewHolder = (id<RCTWeakViewHolder>)_componentData.bridgelessViewManager;
if (!weakViewHolder.weakViews) {
weakViewHolder.weakViews = [NSMapTable strongToWeakObjectsMapTable];
}
[weakViewHolder.weakViews setObject:view forKey:[NSNumber numberWithInteger:tag]];
}
return view;
}
- (void)setProps:(folly::dynamic const &)props forView:(UIView *)view