diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm index b5f45412d257..2578acaf9cca 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm @@ -21,7 +21,7 @@ @implementation RCTImageComponentView { ImageShadowNode::ConcreteState::Shared _state; - RCTImageResponseObserverProxy _imageResponseObserverProxy; + std::shared_ptr _imageResponseObserverProxy; } - (instancetype)initWithFrame:(CGRect)frame @@ -36,7 +36,7 @@ - (instancetype)initWithFrame:(CGRect)frame _imageView.layer.minificationFilter = kCAFilterTrilinear; _imageView.layer.magnificationFilter = kCAFilterTrilinear; - _imageResponseObserverProxy = RCTImageResponseObserverProxy(self); + _imageResponseObserverProxy = std::make_shared(self); self.contentView = _imageView; } diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.cpp b/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.cpp index 5b3e2574a9f3..40b5af0fbf1d 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.cpp +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.cpp @@ -20,11 +20,11 @@ ImageResponseObserverCoordinator::ImageResponseObserverCoordinator( cancelRequest_(std::move(cancelationFunction)) {} void ImageResponseObserverCoordinator::addObserver( - const ImageResponseObserver& observer) const { + std::shared_ptr observer) const { mutex_.lock(); switch (status_) { case ImageResponse::Status::Loading: { - observers_.push_back(&observer); + observers_.push_back(observer); mutex_.unlock(); break; } @@ -32,17 +32,17 @@ void ImageResponseObserverCoordinator::addObserver( auto imageData = imageData_; auto imageMetadata = imageMetadata_; mutex_.unlock(); - observer.didReceiveImage(ImageResponse{imageData, imageMetadata}); + observer->didReceiveImage(ImageResponse{imageData, imageMetadata}); break; } case ImageResponse::Status::Failed: { auto imageErrorData = imageErrorData_; mutex_.unlock(); - observer.didReceiveFailure(ImageLoadError{imageErrorData}); + observer->didReceiveFailure(ImageLoadError{imageErrorData}); break; } case ImageResponse::Status::Cancelled: { - observers_.push_back(&observer); + observers_.push_back(observer); status_ = ImageResponse::Status::Loading; mutex_.unlock(); resumeRequest_(); @@ -52,13 +52,13 @@ void ImageResponseObserverCoordinator::addObserver( } void ImageResponseObserverCoordinator::removeObserver( - const ImageResponseObserver& observer) const { + const std::shared_ptr& observer) const { std::scoped_lock lock(mutex_); // We remove only one element to maintain a balance between add/remove calls. - auto position = std::find(observers_.begin(), observers_.end(), &observer); + auto position = std::find(observers_.begin(), observers_.end(), observer); if (position != observers_.end()) { - observers_.erase(position, observers_.end()); + observers_.erase(position); if (observers_.empty() && status_ == ImageResponse::Status::Loading) { status_ = ImageResponse::Status::Cancelled; @@ -78,7 +78,7 @@ void ImageResponseObserverCoordinator::nativeImageResponseProgress( status_ == ImageResponse::Status::Cancelled); mutex_.unlock(); - for (auto observer : observers) { + for (const auto& observer : observers) { observer->didReceiveProgress(progress, loaded, total); } } @@ -95,7 +95,7 @@ void ImageResponseObserverCoordinator::nativeImageResponseComplete( auto observers = observers_; mutex_.unlock(); - for (auto observer : observers) { + for (const auto& observer : observers) { observer->didReceiveImage(imageResponse); } } @@ -111,7 +111,7 @@ void ImageResponseObserverCoordinator::nativeImageResponseFailed( auto observers = observers_; mutex_.unlock(); - for (auto observer : observers) { + for (const auto& observer : observers) { observer->didReceiveFailure(loadError); } } diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.h index 3aae8ee9ab69..766380829d15 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.h @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -33,12 +34,13 @@ class ImageResponseObserverCoordinator { * If the current image request status is not equal to `Loading`, the observer * will be called immediately. */ - void addObserver(const ImageResponseObserver& observer) const; + void addObserver(std::shared_ptr observer) const; /* * Interested parties may stop observing the image response. */ - void removeObserver(const ImageResponseObserver& observer) const; + void removeObserver( + const std::shared_ptr& observer) const; /* * Platform-specific image loader will call this method with progress updates. @@ -65,7 +67,7 @@ class ImageResponseObserverCoordinator { * List of observers. * Mutable: protected by mutex_. */ - mutable std::vector observers_; + mutable std::vector> observers_; /* * Current status of image loading. diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.mm b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.mm index 601dfe45ac38..20ea791efb2d 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.mm +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.mm @@ -105,7 +105,11 @@ - (ImageRequest)requestImage:(ImageSource)imageSource surfaceId:(SurfaceId)surfa completionBlock:completionBlock]; RCTImageLoaderCancellationBlock cancelationBlock = loaderRequest.cancellationBlock; - sharedCancelationFunction.assign([cancelationBlock]() { cancelationBlock(); }); + sharedCancelationFunction.assign([cancelationBlock]() { + if (cancelationBlock) { + cancelationBlock(); + } + }); }; startRequest();