@@ -38,8 +38,6 @@ - (instancetype)initWithFrame:(CGRect)frame
3838 _imageView.layer .minificationFilter = kCAFilterTrilinear ;
3939 _imageView.layer .magnificationFilter = kCAFilterTrilinear ;
4040
41- _imageResponseObserverProxy = std::make_shared<RCTImageResponseObserverProxy>(self);
42-
4341 self.contentView = _imageView;
4442 }
4543
@@ -124,6 +122,11 @@ - (void)_setStateAndResubscribeImageResponseObserver:(const ImageShadowNode::Con
124122 _state = state;
125123
126124 if (_state) {
125+ // A new observer per subscription: callbacks of a previous request can still be queued on the
126+ // main queue (e.g. after this view was recycled and reused), and must not be applied here.
127+ // The callbacks are matched by the proxy's address. The new proxy is allocated before the
128+ // previous one is released, so two consecutive subscriptions never share an address.
129+ _imageResponseObserverProxy = std::make_shared<RCTImageResponseObserverProxy>(self);
127130 auto &observerCoordinator = _state->getData ().getImageRequest ().getObserverCoordinator ();
128131 observerCoordinator.addObserver (_imageResponseObserverProxy);
129132 }
@@ -140,8 +143,9 @@ - (void)prepareForRecycle
140143
141144- (void )didReceiveImage : (UIImage *)image metadata : (id )metadata fromObserver : (const void *)observer
142145{
143- if (!_eventEmitter || !_state) {
144- // Notifications are delivered asynchronously and might arrive after the view is already recycled.
146+ if (!_eventEmitter || !_state || observer != _imageResponseObserverProxy.get ()) {
147+ // Notifications are delivered asynchronously and might arrive after the view is already recycled,
148+ // or after it has been reused for another image.
145149 // In the future, we should incorporate an `EventEmitter` into a separate object owned by `ImageRequest` or `State`.
146150 // See for more info: T46311063.
147151 return ;
@@ -187,7 +191,7 @@ - (void)didReceiveProgress:(float)progress
187191 total : (int64_t )total
188192 fromObserver : (const void *)observer
189193{
190- if (!_eventEmitter) {
194+ if (!_eventEmitter || observer != _imageResponseObserverProxy. get () ) {
191195 return ;
192196 }
193197
@@ -196,6 +200,10 @@ - (void)didReceiveProgress:(float)progress
196200
197201- (void )didReceiveFailure : (NSError *)error fromObserver : (const void *)observer
198202{
203+ if (observer != _imageResponseObserverProxy.get ()) {
204+ return ;
205+ }
206+
199207 _imageView.image = nil ;
200208
201209 if (!_eventEmitter) {
0 commit comments