react / react/react-native

iOS RCTAssert crash when unmounting near cursor pointer hover effect

Ouverte
#55,489 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Needs: Triage :mag: Platform: iOS
Langage dominant
C++
Étoiles
127k
Forks
25.3k
Merge moyen
1 j 23 h
PR mergées (30 j)
4

Description

Description

iOS app crashing in certain scenarios when unmounting view near hover effects caused by using cursor: 'pointer'.

Requires hover to be enabled, for example with an Apple Pencil Pro or "Send Pointer to Device" active in the simulator.

Reproducible test (Also in supplied reproducer)

function Playground() {
  const [visible, setVisible] = React.useState(true);
  return (
    <View style={styles.container}>
      <Pressable style={styles.button} onPress={() => setVisible(v => !v)}>
        <Text>Click Me</Text>
      </Pressable>
      {visible && <Text>Hello World</Text>}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 10,
  },
  button: {
    cursor: 'pointer',
    backgroundColor: 'salmon',
    width: 200,
  },
});

A peek in the debugger reveals that self.currentContainerView.subviews has a _UIPointerEffectPlatterView in the expected index location instead of the view in question.

Also reproducible on 0.79, 0.81 and in the latest main branch.

As a side note, I've also seen these pointer hover effects being applied to views even when cursor: 'pointer' is not set, which can cause the same typeof assertion crash. But have not been able to reproduce this in a stable way. Hopefully it's the same root cause.

Steps to reproduce
  1. Hover the Click Me button with hover enabled (e.g. Apple Pencil Pro or "Send Pointer to Device" in simulator)
  2. Click the button.
  3. Crash
React Native Version

0.81.6

Affected Platforms

Runtime - iOS

Output of npx @react-native-community/cli info
System:
  OS: macOS 14.5
  CPU: (8) arm64 Apple M1
  Memory: 120.50 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 22.15.0
    path: /usr/local/bin/node
  Yarn:
    version: 1.22.22
    path: /usr/local/bin/yarn
  npm:
    version: 10.9.2
    path: /usr/local/bin/npm
  Watchman:
    version: 2026.01.12.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.13.0
    path: /usr/local/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.2
      - iOS 18.2
      - macOS 15.2
      - tvOS 18.2
      - visionOS 2.2
      - watchOS 11.2
  Android SDK:
    API Levels:
      - "29"
      - "31"
      - "33"
      - "34"
      - "35"
    Build Tools:
      - 29.0.3
      - 30.0.3
      - 31.0.0
      - 33.0.0
      - 35.0.0
    System Images:
      - android-29 | Google APIs ARM 64 v8a
      - android-31 | Google APIs ARM 64 v8a
      - android-33 | Google APIs ARM 64 v8a
      - android-36.1 | Google APIs ARM 64 v8a
      - android-36.1 | Google Play ARM 64 v8a
      - android-36 | Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2025.2 AI-252.28238.7.2523.14688667
  Xcode:
    version: 16.2/16C5032a
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 22.0.2
    path: /usr/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react: Not Found
  react-native: Not Found
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: false
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: true
Stacktrace or Logs
*** Assertion failure in -[RCTViewComponentView unmountChildComponentView:index:](), /Users/andreashogstrom/Code/react-native/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm:173
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempt to unmount a view which has a different index. (parent: <RCTRootComponentView: 0x111039af0; frame = (0 0; 1032 1376); tag = 11; layer = <CALayer: 0x600000231400>>, child: <RCTParagraphComponentView: 0x110e67ec0; frame = (10 117; 1012 17); opaque = NO; tag = 628; layer = <CALayer: 0x60000031d7c0>; attributedText = Hello World{
    EventEmitter = {length = 8, bytes = 0x1833700300600000};
    NSBackgroundColor = "UIExtendedSRGBColorSpace 0 0 0 0";
    NSColor = "UIExtendedSRGBColorSpace 0 0 0 1";
    NSFont = "<UICTFont: 0x1111713e0> font-family: \".SFUI-Regular\"; font-weight: normal; font-style: normal; font-size: 14.00pt";
}>, index: 6, actual index: 9, tag at index: 624)'
*** First throw call stack:
(
	0   CoreFoundation                      0x00000001804b910c __exceptionPreprocess + 172
	1   libobjc.A.dylib                     0x0000000180092da8 objc_exception_throw + 72
	2   Foundation                          0x0000000180e67e68 -[NSMutableDictionary(NSMutableDictionary) classForCoder] + 0
	3   RNTester.debug.dylib                0x00000001074f5f74 -[RCTViewComponentView unmountChildComponentView:index:] + 2304
	4   RNTester.debug.dylib                0x00000001074594f0 _ZL27RCTPerformMountInstructionsRKNSt3__16vectorIN8facebook5react18ShadowViewMutationENS_9allocatorIS3_EEEEP24RCTComponentViewRegistryR41RCTMountingTransactionObserverCoordinatori + 1340
	5   RNTester.debug.dylib                0x0000000107458fa8 _ZZ41-[RCTMountingManager performTransaction:]ENK3$_1clERKN8facebook5react19MountingTransactionERKNS1_16SurfaceTelemetryE + 80
	6   RNTester.debug.dylib                0x0000000107458f4c _ZNSt3__18__invokeB8de180100IRZ41-[RCTMountingManager performTransaction:]E3$_1JRKN8facebook5react19MountingTransactionERKNS4_16SurfaceTelemetryEEEEDTclclsr3stdE7declvalIT_EEspclsr3stdE7declvalIT	7   RNTester.debug.dylib                0x0000000107458ef4 _ZNSt3__128__invoke_void_return_wrapperIvLb1EE6__callB8de180100IJRZ41-[RCTMountingManager performTransaction:]E3$_1RKN8facebook5react19MountingTransactionERKNS6_16SurfaceTelemetryEEEEvDpOT_ + 40
	8   RNTester.debug.dylib                0x0000000107458ec0 _ZNSt3__110__function12__alloc_funcIZ41-[RCTMountingManager performTransaction:]E3$_1NS_9allocatorIS2_EEFvRKN8facebook5react19MountingTransactionERKNS6_16SurfaceTelemetryEEEclB8de180100ES9_SC_ + 	9   RNTester.debug.dylib                0x0000000107457d3c _ZNSt3__110__function6__funcIZ41-[RCTMountingManager performTransaction:]E3$_1NS_9allocatorIS2_EEFvRKN8facebook5react19MountingTransactionERKNS6_16SurfaceTelemetryEEEclES9_SC_ + 44
	10  RNTester.debug.dylib                0x0000000107212cc4 _ZNKSt3__110__function12__value_funcIFvRKN8facebook5react19MountingTransactionERKNS3_16SurfaceTelemetryEEEclB8de180100ES6_S9_ + 84
	11  RNTester.debug.dylib                0x0000000107211c28 _ZNKSt3__18functionIFvRKN8facebook5react19MountingTransactionERKNS2_16SurfaceTelemetryEEEclES5_S8_ + 40
	12  RNTester.debug.dylib                0x0000000107211a58 _ZNK8facebook5react19TelemetryController15pullTransactionERKNSt3__18functionIFvRKNS0_19MountingTransactionERKNS0_16SurfaceTelemetryEEEESD_SD_ + 300
	13  RNTester.debug.dylib                0x00000001074530c8 -[RCTMountingManager performTransaction:] + 564
	14  RNTester.debug.dylib                0x0000000107452e44 -[RCTMountingManager initiateTransaction:] + 428
	15  RNTester.debug.dylib                0x0000000107452820 __42-[RCTMountingManager scheduleTransaction:]_block_invoke + 324
	16  RNTester.debug.dylib                0x0000000106f0f0f0 __RCTExecuteOnMainQueue_block_invoke + 40
	17  libdispatch.dylib                   0x0000000102ad8cd8 _dispatch_call_block_and_release + 24
	18  libdispatch.dylib                   0x0000000102ada5d0 _dispatch_client_callout + 16
	19  libdispatch.dylib                   0x0000000102aea41c _dispatch_main_queue_drain + 1228
	20  libdispatch.dylib                   0x0000000102ae9f40 _dispatch_main_queue_callback_4CF + 40
	21  CoreFoundation                      0x000000018041cdbc __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
	22  CoreFoundation                      0x0000000180417318 __CFRunLoopRun + 1944
	23  CoreFoundation                      0x0000000180416704 CFRunLoopRunSpecific + 552
	24  GraphicsServices                    0x0000000190604b10 GSEventRunModal + 160
	25  UIKitCore                           0x0000000185b39180 -[UIApplication _run] + 796
	26  UIKitCore                           0x0000000185b3d378 UIApplicationMain + 124
	27  RNTester.debug.dylib                0x0000000106d657c4 __debug_main_executable_dylib_entry_point + 96
	28  dyld                                0x0000000102bed410 start_sim + 20
	29  ???                                 0x00000001025660e0 0x0 + 4334182624
	30  ???                                 0x1c56000000000000 0x0 + 2041819481059098624
)
libc++abi: terminating due to uncaught exception of type NSException
MANDATORY Reproducer

https://github.com/AndreasHogstrom/react-native/blob/main/packages/rn-tester/js/examples/Playground/RNTesterPlayground.js

Screenshots and Videos

https://github.com/user-attachments/assets/f29b09c4-6041-4878-aad7-cea27b2ff473

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez avec le reproducteur RNTester Playground fourni et activez le survol du pointeur iOS avant de basculer la vue. Inspectez l’assertion dans RCTViewComponentView.mm autour de la ligne 173, en particulier la divergence impliquant _UIPointerEffectPlatterView. Le travail est terminé lorsque le unmount reproductible ne provoque plus de plantage avec l’assertion affichée.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
objective-c, react-native
Domaine
mobile-dev
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
Calme
Clarté
Plutôt claire
Accessibilité débutants
45/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.