georstat/react-native-image-cache

Crash when using with react-native-shared-element on iOS

Closed this issue · 10 comments

First of all, thank you for creating this library.

It works very well except when I use the image as a shared element using react-native-shared-element

2021-11-09 17:35:17.295688+0100 Glue[30583:715845] *** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <RNSharedElementNode 0x600003d16450> for the key path "image" from <RCTUIImageViewAnimated 0x7f8c90842e50> because it is not registered as an observer.'
*** First throw call stack:
(
	0   CoreFoundation                      0x00007fff20422fba __exceptionPreprocess + 242
	1   libobjc.A.dylib                     0x00007fff20193ff5 objc_exception_throw + 48
	2   Foundation                          0x00007fff207c2ee4 -[NSObject(NSKeyValueObserverRegistration) _removeObserver:forProperty:] + 689
	3   Foundation                          0x00007fff207c32de -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] + 74
	4   Glue                                0x000000010e2a7561 -[RNSharedElementNode removeContentObservers:] + 145
	5   Glue                                0x000000010e2a6420 -[RNSharedElementNode updateResolvedSource:] + 1648
	6   Glue                                0x000000010e2a7736 -[RNSharedElementNode setRefCount:] + 182
	7   Glue                                0x000000010e2a9425 -[RNSharedElementNodeManager release:] + 149
	8   Glue                                0x000000010e2b3c89 -[RNSharedElementTransitionItem setNode:] + 217
	9   Glue                                0x000000010e2ac39e -[RNSharedElementTransition dealloc] + 318
	10  CoreFoundation                      0x00007fff20322935 __RELEASE_OBJECTS_IN_THE_ARRAY__ + 119
	11  CoreFoundation                      0x00007fff20322877 -[__NSArrayM dealloc] + 278
	12  libobjc.A.dylib                     0x00007fff20191604 _ZN11objc_object17sidetable_releaseEbb + 174
	13  libobjc.A.dylib                     0x00007fff2018d8ad _object_remove_assocations + 562
	14  libobjc.A.dylib                     0x00007fff2018ac02 objc_destructInstance + 84
	15  libobjc.A.dylib                     0x00007fff20190d88 -[NSObject dealloc] + 21
	16  UIKitCore                           0x00007fff246f4cee -[UIResponder dealloc] + 145
	17  UIKitCore                           0x00007fff24be8447 -[UIView dealloc] + 1018
	18  Glue                                0x000000010e4d9fbf -[RCTView dealloc] + 191
	19  CoreFoundation                      0x00007fff20322935 __RELEASE_OBJECTS_IN_THE_ARRAY__ + 119
	20  CoreFoundation                      0x00007fff20322877 -[__NSArrayM dealloc] + 278
	21  libobjc.A.dylib                     0x00007fff20191604 _ZN11objc_object17sidetable_releaseEbb + 174
	22  libobjc.A.dylib                     0x00007fff20192dc7 _ZN19AutoreleasePoolPage12releaseUntilEPP11objc_object + 175
	23  libobjc.A.dylib                     0x00007fff20192cb6 objc_autoreleasePoolPop + 185
	24  CoreFoundation                      0x00007fff20432036 _CFAutoreleasePoolPop + 22
	25  CoreFoundation                      0x00007fff2038fd5c __CFRunLoopPerCalloutARPEnd + 41
	26  CoreFoundation                      0x00007fff2038b1a2 __CFRunLoopRun + 2838
	27  CoreFoundation                      0x00007fff2038a1a7 CFRunLoopRunSpecific + 567
	28  GraphicsServices                    0x00007fff2b874d85 GSEventRunModal + 139
	29  UIKitCore                           0x00007fff246c14df -[UIApplication _run] + 912
	30  UIKitCore                           0x00007fff246c639c UIApplicationMain + 101
	31  Glue                                0x000000010dc350b8 main + 104
	32  libdyld.dylib                       0x00007fff2025abbd start + 1
	33  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <RNSharedElementNode 0x600003d16450> for the key path "image" from <RCTUIImageViewAnimated 0x7f8c90842e50> because it is not registered as an observer.'
terminating with uncaught exception of type NSException
CoreSimulator 776.4 - Device: iPhone Xʀ (E2D79EE1-C0E9-4753-967C-216C331D8610) - Runtime: iOS 14.5 (18E182) - DeviceType: iPhone Xʀ

Reproducible here:
https://github.com/kamiranoff/crashOnSharedElement/tree/master

How to reproduce:
start the ios project on a simulator and press on the image

Hi @kamiranoff, can you please create a repo with a minimum reproducible example? Thanks!

@efstathiosntonas, sorry for the delay, I created a repository, with a reproducible example. In my use case, I use react-native-shared-element and react-navigation-shared-element so it might not be the most common use case.

Let me know if anything or if you want me to improve in the minimum reproducible example.

The same test case works with Image from React Native or FastImage from react-native-fast-image so it might be related to this library.

Thank you!

Hi @kamiranoff,

We will look into it as soon as possible

@geobako I think this might be a bug with react-native-shared-elements libs, it seems it doesn’t like the animations being used upon the Image component. We’re not doing something special with it, just a fade-in/fade-out animation.

@efstathiosntonas probably. I will run some tests to find out

@kamiranoff @geobako

Runned the repo on real iPhone XS using iOS 15 and a iPhone 13 simulator on iOS 15 , the only change i've made was:

before: <-- crashes

<TouchableOpacity onPress={() => goBack()}>
      <SharedElement id="xmen">
        <CachedImage
          source="https://upload.wikimedia.org/wikipedia/en/3/3b/Magnetodebut.png"
          style={{
            width: 300,
            height: 400,
          }}
          resizeMode="cover"
        />
      </SharedElement>
    </TouchableOpacity>

after: <--- no crash


 <TouchableOpacity onPress={() => goBack()}>
      <SharedElement id="xmen">
        <View style={{flex: 1}}>
          <CachedImage
            source="https://upload.wikimedia.org/wikipedia/en/3/3b/Magnetodebut.png"
            style={{
              width: 300,
              height: 400,
            }}
            resizeMode="cover"
          />
        </View>
      </SharedElement>
    </TouchableOpacity>


so by wrapping the CachedImage inside a View with flex:1 as a style seems to fix the issue.

@kamiranoff can you please confirm? Thanks

IMG_8730.MP4

So probably an animated component as a direct child of shared element causes this

@efstathiosntonas, nice find, it does fix the crash also in the simulator, running iOS 14.5.

the transition from the shared element is lost in the process.

If I add the same style to the View and the image I do get the transition back

 <View
          style={{
            width: 300,
            height: 400,
          }}>
          <CachedImage
            source="https://upload.wikimedia.org/wikipedia/en/3/3b/Magnetodebut.png"
            style={{
              width: 300,
              height: 400,
            }}
            resizeMode="cover"
          />
        </View>

But I run into this issue:
IjzerenHein/react-native-shared-element#21

Where the image transition is not applied correctly. But that could be more related to react-native-shared-element

@kamiranoff glad that we at least stopped it from crashing 😀, @geobako can you please investigate the broken transition issue, it seems that we have to make the Image a direct child (according to the linked issue above) and avoid the hack we used above.

Hi guys, sorry for the late response.

I tried some examples but it seems that this bug is not related to our package but to react-native-shared-element so I will close this issue for now