diff --git a/React/Fabric/RCTSurfacePresenter.mm b/React/Fabric/RCTSurfacePresenter.mm index dd7a1bd0fb5..59937990722 100644 --- a/React/Fabric/RCTSurfacePresenter.mm +++ b/React/Fabric/RCTSurfacePresenter.mm @@ -80,7 +80,7 @@ static BackgroundExecutor RCTGetBackgroundExecutor() RuntimeExecutor _runtimeExecutor; // Protected by `_schedulerLifeCycleMutex`. butter::shared_mutex _observerListMutex; - NSMutableArray> *_observers; + std::vector<__weak id> _observers; // Protected by `_observerListMutex`. } - (instancetype)initWithContextContainer:(ContextContainer::Shared)contextContainer @@ -96,8 +96,6 @@ static BackgroundExecutor RCTGetBackgroundExecutor() _mountingManager.contextContainer = contextContainer; _mountingManager.delegate = self; - _observers = [NSMutableArray array]; - _scheduler = [self _createScheduler]; auto reactNativeConfig = _contextContainer->at>("ReactNativeConfig"); @@ -386,13 +384,17 @@ static BackgroundExecutor RCTGetBackgroundExecutor() - (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 @@ -401,8 +403,13 @@ static BackgroundExecutor RCTGetBackgroundExecutor() { 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]; } @@ -413,12 +420,29 @@ static BackgroundExecutor RCTGetBackgroundExecutor() { 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