From 6ba3474e00934aed20284bc11ad7985463644612 Mon Sep 17 00:00:00 2001 From: wwwcg Date: Thu, 31 Aug 2023 17:58:02 +0800 Subject: [PATCH] fix(ios): NativeRenderView leak --- .../native/ios/renderer/NativeRenderImpl.mm | 37 ++++++------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/renderer/native/ios/renderer/NativeRenderImpl.mm b/renderer/native/ios/renderer/NativeRenderImpl.mm index e6176a89f47..87be2c192e0 100644 --- a/renderer/native/ios/renderer/NativeRenderImpl.mm +++ b/renderer/native/ios/renderer/NativeRenderImpl.mm @@ -169,7 +169,9 @@ @interface NativeRenderImpl() { // Keyed by viewName NSMutableDictionary *_componentDataByName; - NSMutableSet> *_componentTransactionListeners; + // Listeners such as ScrollView/ListView etc. witch will listen to start layout event + // The implementation here needs to be improved to provide a registration mechanism. + NSHashTable> *_componentTransactionListeners; std::weak_ptr _domManager; std::mutex _renderQueueLock; @@ -209,7 +211,7 @@ - (void)initContext { _viewRegistry = [[NativeRenderComponentMap alloc] init]; _viewRegistry.requireInMainThread = YES; _pendingUIBlocks = [NSMutableArray new]; - _componentTransactionListeners = [NSMutableSet new]; + _componentTransactionListeners = [NSHashTable weakObjectsHashTable]; _componentDataByName = [NSMutableDictionary dictionaryWithCapacity:64]; NativeRenderScreenScale(); NativeRenderScreenSize(); @@ -222,7 +224,7 @@ - (void)invalidate { NativeRenderImpl *strongSelf = weakSelf; if (strongSelf) { strongSelf->_viewRegistry = nil; - strongSelf->_componentTransactionListeners = nil; + [strongSelf->_componentTransactionListeners removeAllObjects]; [[NSNotificationCenter defaultCenter] removeObserver:strongSelf]; } }); @@ -431,8 +433,7 @@ - (void)setFrame:(CGRect)frame forRootView:(UIView *)view { */ - (void)purgeChildren:(NSArray> *)children onRootTag:(NSNumber *)rootTag - fromRegistry:(NativeRenderComponentMap *)componentMap { - NSMutableDictionary> *registry = [componentMap componentsForRootTag:rootTag]; + fromRegistry:(NSMutableDictionary> *)registry { for (id child in children) { NativeRenderTraverseViewNodes(registry[child.componentTag], ^(id subview) { NSAssert(![subview isNativeRenderRootView], @"Root views should not be unregistered"); @@ -440,9 +441,6 @@ - (void)purgeChildren:(NSArray> *)children [subview performSelector:@selector(invalidate)]; } [registry removeObjectForKey:subview.componentTag]; - if (registry == (NSMutableDictionary> *)self->_viewRegistry) { - [self->_componentTransactionListeners removeObject:subview]; - } }); } } @@ -458,21 +456,6 @@ - (void)purgeViewsFromComponentTags:(NSArray *)componentTags onRootT } } -- (void)purgeChildren:(NSArray> *)children fromRegistry:(NSMutableDictionary> *)registry { - for (id child in children) { - NativeRenderTraverseViewNodes(registry[child.componentTag], ^(id subview) { - NSAssert(![subview isNativeRenderRootView], @"Root views should not be unregistered"); - if ([subview respondsToSelector:@selector(invalidate)]) { - [subview performSelector:@selector(invalidate)]; - } - [registry removeObjectForKey:subview.componentTag]; - if (registry == (NSMutableDictionary> *)self->_viewRegistry) { - [self->_componentTransactionListeners removeObject:subview]; - } - }); - } -} - - (void)removeChildren:(NSArray> *)children fromContainer:(id)container { for (id removedChild in children) { [container removeNativeRenderSubview:removedChild]; @@ -838,14 +821,15 @@ - (void)deleteRenderNodesIds:(std::vector> &&)no #endif std::lock_guard lock([self renderQueueLock]); NSNumber *rootTag = @(strongRootNode->GetId()); + NSMutableDictionary *currentRegistry = [_renderObjectRegistry componentsForRootTag:rootTag]; for (auto dom_node : nodes) { int32_t tag = dom_node->GetRenderInfo().id; - NativeRenderObjectView *renderObject = [_renderObjectRegistry componentForTag:@(tag) onRootTag:rootTag]; + NativeRenderObjectView *renderObject = [currentRegistry objectForKey:@(tag)]; [renderObject dirtyPropagation:NativeRenderUpdateLifecycleLayoutDirtied]; if (renderObject) { [renderObject removeFromNativeRenderSuperview]; - [self purgeChildren:@[renderObject] onRootTag:rootTag fromRegistry:_renderObjectRegistry]; + [self purgeChildren:@[renderObject] onRootTag:rootTag fromRegistry:currentRegistry]; } } __weak NativeRenderImpl *weakSelf = self; @@ -870,7 +854,8 @@ - (void)deleteRenderNodesIds:(std::vector> &&)no [view removeFromNativeRenderSuperview]; [views addObject:view]; } - [strongSelf purgeChildren:views onRootTag:rootTag fromRegistry:strongSelf->_viewRegistry]; + NSMutableDictionary *currentViewRegistry = [strongSelf->_viewRegistry componentsForRootTag:rootTag]; + [strongSelf purgeChildren:views onRootTag:rootTag fromRegistry:currentViewRegistry]; for (UIView *view in parentViews) { [view clearSortedSubviews]; [view didUpdateNativeRenderSubviews];