diff --git a/React/Fabric/RCTSurfacePresenter.mm b/React/Fabric/RCTSurfacePresenter.mm index 89e6840ea0ffaa..4e09b1ccea8468 100644 --- a/React/Fabric/RCTSurfacePresenter.mm +++ b/React/Fabric/RCTSurfacePresenter.mm @@ -80,8 +80,7 @@ @implementation RCTSurfacePresenter { RuntimeExecutor _runtimeExecutor; // Protected by `_schedulerLifeCycleMutex`. butter::shared_mutex _observerListMutex; - NSMutableArray> *_observers; - RCTImageLoader *_imageLoader; + std::vector<__weak id> _observers; // Protected by `_observerListMutex`. } - (instancetype)initWithContextContainer:(ContextContainer::Shared)contextContainer @@ -97,8 +96,6 @@ - (instancetype)initWithContextContainer:(ContextContainer::Shared)contextContai _mountingManager.contextContainer = contextContainer; _mountingManager.delegate = self; - _observers = [NSMutableArray array]; - _scheduler = [self _createScheduler]; } @@ -364,13 +361,17 @@ - (void)schedulerDidSetIsJSResponder:(BOOL)isJSResponder - (void)addObserver:(id)observer { std::unique_lock lock(_observerListMutex); - [self->_observers addObject:observer]; + _observers.push_back(observer); } - (void)removeObserver:(id)observer { std::unique_lock lock(_observerListMutex); - [self->_observers removeObject:observer]; + std::vector<__weak id>::const_iterator it = + std::find(_observers.begin(), _observers.end(), observer); + if (it != _observers.end()) { + _observers.erase(it); + } } #pragma mark - RCTMountingManagerDelegate @@ -379,8 +380,13 @@ - (void)mountingManager:(RCTMountingManager *)mountingManager willMountComponent { RCTAssertMainQueue(); - std::shared_lock lock(_observerListMutex); - for (id observer in _observers) { + NSArray> *observersCopy; + { + std::shared_lock lock(_observerListMutex); + observersCopy = [self _getObservers]; + } + + for (id observer in observersCopy) { if ([observer respondsToSelector:@selector(willMountComponentsWithRootTag:)]) { [observer willMountComponentsWithRootTag:rootTag]; } @@ -391,12 +397,29 @@ - (void)mountingManager:(RCTMountingManager *)mountingManager didMountComponents { RCTAssertMainQueue(); - std::shared_lock lock(_observerListMutex); - for (id observer in _observers) { + NSArray> *observersCopy; + { + std::shared_lock lock(_observerListMutex); + observersCopy = [self _getObservers]; + } + + for (id observer in observersCopy) { if ([observer respondsToSelector:@selector(didMountComponentsWithRootTag:)]) { [observer didMountComponentsWithRootTag:rootTag]; } } } +- (NSArray> *)_getObservers +{ + NSMutableArray> *observersCopy = [NSMutableArray new]; + for (id observer : _observers) { + if (observer) { + [observersCopy addObject:observer]; + } + } + + return observersCopy; +} + @end