picker icon indicating copy to clipboard operation
picker copied to clipboard

[IOS] crash on react-native 0.77(new architecture)

Open huanguolin opened this issue 7 months ago • 28 comments

Library version: 2.11.0 React native version: 0.77.2, new architecture enabled It occasionally crashes when using the selector:


Crashed: com.apple.main-thread
0  libobjc.A.dylib                0x3c20 objc_msgSend + 32
1  UIKitCore                      0x1103d3c -[UIPickerView hitTest:withEvent:] + 432
2  LeySerKids                     0x6cbfa8 -[RCTViewComponentView betterHitTest:withEvent:] + 627 (RCTViewComponentView.mm:627)
3  LeySerKids                     0x6cc0bc -[RCTViewComponentView hitTest:withEvent:] + 640 (RCTViewComponentView.mm:640)
4  LeySerKids                     0x6cbfa8 -[RCTViewComponentView betterHitTest:withEvent:] + 627 (RCTViewComponentView.mm:627)
5  LeySerKids                     0x6cc0bc -[RCTViewComponentView hitTest:withEvent:] + 640 (RCTViewComponentView.mm:640)
6  UIKitCore                      0x7a3cc -[UIView(Geometry) _hitTest:withEvent:windowServerHitTestWindow:] + 84
7  UIKitCore                      0x7a210 __38-[UIView(Geometry) hitTest:withEvent:]_block_invoke + 92
8  CoreFoundation                 0x25430 __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__ + 24
9  CoreFoundation                 0x8e4ac -[__NSSingleObjectArrayI enumerateObjectsWithOptions:usingBlock:] + 92
10 UIKitCore                      0xda67c -[UIView(Geometry) hitTest:withEvent:] + 480
11 UIKitCore                      0x7a3cc -[UIView(Geometry) _hitTest:withEvent:windowServerHitTestWindow:] + 84
12 UIKitCore                      0x7a210 __38-[UIView(Geometry) hitTest:withEvent:]_block_invoke + 92
13 CoreFoundation                 0x25430 __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__ + 24
14 CoreFoundation                 0x8e4ac -[__NSSingleObjectArrayI enumerateObjectsWithOptions:usingBlock:] + 92
15 UIKitCore                      0xda67c -[UIView(Geometry) hitTest:withEvent:] + 480
16 UIKitCore                      0x1553260 -[UITransitionView hitTest:withEvent:] + 56
17 UIKitCore                      0x7a3cc -[UIView(Geometry) _hitTest:withEvent:windowServerHitTestWindow:] + 84
18 UIKitCore                      0x7a210 __38-[UIView(Geometry) hitTest:withEvent:]_block_invoke + 92
19 CoreFoundation                 0x25430 __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__ + 24
20 CoreFoundation                 0x25310 -[__NSArrayM enumerateObjectsWithOptions:usingBlock:] + 432
21 UIKitCore                      0xda67c -[UIView(Geometry) hitTest:withEvent:] + 480
22 UIKitCore                      0x7a3cc -[UIView(Geometry) _hitTest:withEvent:windowServerHitTestWindow:] + 84
23 UIKitCore                      0x595f8 -[UIWindow _hitTestLocation:sceneLocationZ:inScene:withWindowServerHitTestWindow:event:] + 96
24 UIKitCore                      0x593a4 __75+[UIWindow _hitTestToPoint:scenePointZ:forEvent:windowServerHitTestWindow:]_block_invoke + 68
25 UIKitCore                      0x5870c __64-[UIWindowScene _topVisibleWindowEnumeratingAsCopy:passingTest:]_block_invoke + 116
26 UIKitCore                      0x583f0 -[UIWindowScene _enumerateWindowsIncludingInternalWindows:onlyVisibleWindows:asCopy:stopped:withBlock:] + 312
27 UIKitCore                      0x4bb9c -[UIWindowScene _topVisibleWindowEnumeratingAsCopy:passingTest:] + 416
28 UIKitCore                      0x11bf28 +[UIWindow _hitTestToPoint:scenePointZ:forEvent:windowServerHitTestWindow:] + 220
29 UIKitCore                      0x11bdfc -[UIWindow _targetWindowForPathIndex:atPoint:scenePointZ:forEvent:windowServerHitTestWindow:] + 188
30 UIKitCore                      0x117e0c __startNewUITouch + 604
31 UIKitCore                      0x11a4a20 ____updateTouchesWithDigitizerEventAndDetermineIfShouldSend_block_invoke.30 + 316
32 UIKitCore                      0x1ad720 _UIEventHIDEnumerateChildren + 172
33 UIKitCore                      0x1ac1bc __dispatchPreprocessedEventFromEventQueue + 2596
34 UIKitCore                      0x1b5994 __processEventQueue + 5696
35 UIKitCore                      0xadf40 updateCycleEntry + 160
36 UIKitCore                      0xabcb8 _UIUpdateSequenceRun + 84
37 UIKitCore                      0xab908 schedulerStepScheduledMainSection + 172
38 UIKitCore                      0xac87c runloopSourceCallback + 92
39 CoreFoundation                 0x57088 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28
40 CoreFoundation                 0x5701c __CFRunLoopDoSource0 + 176
41 CoreFoundation                 0x54b08 __CFRunLoopDoSources0 + 244
42 CoreFoundation                 0x53d04 __CFRunLoopRun + 840
43 CoreFoundation                 0x535b8 CFRunLoopRunSpecific + 572
44 GraphicsServices               0x11c4 GSEventRunModal + 164
45 UIKitCore                      0x3de2c0 -[UIApplication _run] + 816
46 UIKitCore                      0x48cddc UIApplicationMain + 340
47 UIKitCore                      0x7b9b20 block_destroy_helper.23 + 10212
48 LeySerKids                     0x8ed4 main + 4375416532 (AppDelegate.swift:4375416532)
49 ???                            0x1b04a0d34 (缺少)

com.apple.uikit.eventfetch-thread
0  libsystem_kernel.dylib         0x1728 mach_msg2_trap + 8
1  libsystem_kernel.dylib         0x4e38 mach_msg2_internal + 80
2  libsystem_kernel.dylib         0x4d50 mach_msg_overwrite + 424
3  libsystem_kernel.dylib         0x4b9c mach_msg + 24
4  CoreFoundation                 0x547cc __CFRunLoopServiceMachPort + 160
5  CoreFoundation                 0x53e78 __CFRunLoopRun + 1212
6  CoreFoundation                 0x535b8 CFRunLoopRunSpecific + 572
7  Foundation                     0xb7000 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212
8  Foundation                     0xb6e50 -[NSRunLoop(NSRunLoop) runUntilDate:] + 64
9  UIKitCore                      0x3f1714 -[UIEventFetcher threadMain] + 420
10 Foundation                     0xc8158 __NSThread__start__ + 724
11 libsystem_pthread.dylib        0x637c _pthread_start + 136
12 libsystem_pthread.dylib        0x1494 thread_start + 8

Thread
0  libsystem_kernel.dylib         0x14b0 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x4cc8 _pthread_wqthread + 364
2  libsystem_pthread.dylib        0x1488 start_wqthread + 8

com.google.firebase.crashlytics.MachExceptionServer
0  LeySerKids                     0x7283c FIRCLSProcessRecordAllThreads + 392 (FIRCLSProcess.c:392)
1  LeySerKids                     0x72c1c FIRCLSProcessRecordAllThreads + 423 (FIRCLSProcess.c:423)
2  LeySerKids                     0x6a954 FIRCLSHandler + 34 (FIRCLSHandler.m:34)
3  LeySerKids                     0x6d2c8 FIRCLSMachExceptionServer + 525 (FIRCLSMachException.c:525)
4  libsystem_pthread.dylib        0x637c _pthread_start + 136
5  libsystem_pthread.dylib        0x1494 thread_start + 8

com.facebook.react.runtime.JavaScript
0  libsystem_kernel.dylib         0x1728 mach_msg2_trap + 8
1  libsystem_kernel.dylib         0x4e38 mach_msg2_internal + 80
2  libsystem_kernel.dylib         0x4d50 mach_msg_overwrite + 424
3  libsystem_kernel.dylib         0x4b9c mach_msg + 24
4  CoreFoundation                 0x547cc __CFRunLoopServiceMachPort + 160
5  CoreFoundation                 0x53e78 __CFRunLoopRun + 1212
6  CoreFoundation                 0x535b8 CFRunLoopRunSpecific + 572
7  LeySerKids                     0x9bc008 +[RCTJSThreadManager runRunLoop] + 102 (RCTJSThreadManager.mm:102)
8  Foundation                     0xc8158 __NSThread__start__ + 724
9  libsystem_pthread.dylib        0x637c _pthread_start + 136
10 libsystem_pthread.dylib        0x1494 thread_start + 8

hades
0  libsystem_kernel.dylib         0x7030 __psynch_cvwait + 8
1  libsystem_pthread.dylib        0x3a50 _pthread_cond_wait + 1204
2  libc++.1.dylib                 0x21584 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 28
3  hermes                         0xcc7fc hermes::vm::HadesGC::Executor::worker() + 116
4  hermes                         0xcc764 void* std::__1::__thread_proxy[abi:v160006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, hermes::vm::HadesGC::Executor::Executor()::'lambda'()>>(void*) + 44
5  libsystem_pthread.dylib        0x637c _pthread_start + 136
6  libsystem_pthread.dylib        0x1494 thread_start + 8

com.apple.NSURLConnectionLoader
0  libsystem_kernel.dylib         0x1728 mach_msg2_trap + 8
1  libsystem_kernel.dylib         0x4e38 mach_msg2_internal + 80
2  libsystem_kernel.dylib         0x4d50 mach_msg_overwrite + 424
3  libsystem_kernel.dylib         0x4b9c mach_msg + 24
4  CoreFoundation                 0x547cc __CFRunLoopServiceMachPort + 160
5  CoreFoundation                 0x53e78 __CFRunLoopRun + 1212
6  CoreFoundation                 0x535b8 CFRunLoopRunSpecific + 572
7  CFNetwork                      0xfdf44 +[__CFN_CoreSchedulingSetRunnable _run:] + 416
8  Foundation                     0xc8158 __NSThread__start__ + 724
9  libsystem_pthread.dylib        0x637c _pthread_start + 136
10 libsystem_pthread.dylib        0x1494 thread_start + 8

Thread
0  libsystem_kernel.dylib         0x14b0 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x4cc8 _pthread_wqthread + 364
2  libsystem_pthread.dylib        0x1488 start_wqthread + 8

Thread
0  libsystem_pthread.dylib        0x1480 start_wqthread + 8892318846

Thread
0  libsystem_pthread.dylib        0x1480 start_wqthread + 8892318846

Thread
0  libsystem_pthread.dylib        0x1480 start_wqthread + 8892318846

Thread
0  libsystem_kernel.dylib         0x14b0 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x4cc8 _pthread_wqthread + 364
2  libsystem_pthread.dylib        0x1488 start_wqthread + 8

JavaScriptCore libpas scavenger
0  libsystem_kernel.dylib         0x7030 __psynch_cvwait + 8
1  libsystem_pthread.dylib        0x3a50 _pthread_cond_wait + 1204
2  JavaScriptCore                 0x15a3fe8 scavenger_thread_main + 1316
3  libsystem_pthread.dylib        0x637c _pthread_start + 136
4  libsystem_pthread.dylib        0x1494 thread_start + 8

AudioSession - RootQueue
0  libsystem_kernel.dylib         0x16bc semaphore_timedwait_trap + 8
1  libdispatch.dylib              0x46e8 _dispatch_sema4_timedwait + 64
2  libdispatch.dylib              0x4ce8 _dispatch_semaphore_wait_slow + 76
3  libdispatch.dylib              0x15b60 _dispatch_worker_thread + 324
4  libsystem_pthread.dylib        0x637c _pthread_start + 136
5  libsystem_pthread.dylib        0x1494 thread_start + 8

AudioSession - RootQueue
0  libsystem_kernel.dylib         0x16bc semaphore_timedwait_trap + 8
1  libdispatch.dylib              0x46e8 _dispatch_sema4_timedwait + 64
2  libdispatch.dylib              0x4ce8 _dispatch_semaphore_wait_slow + 76
3  libdispatch.dylib              0x15b60 _dispatch_worker_thread + 324
4  libsystem_pthread.dylib        0x637c _pthread_start + 136
5  libsystem_pthread.dylib        0x1494 thread_start + 8

huanguolin avatar May 21 '25 04:05 huanguolin

+1 same here

jingp-ofload avatar May 26 '25 01:05 jingp-ofload

It it related to this same issue: https://github.com/react-native-picker/picker/issues/519

hollanderbart avatar May 27 '25 11:05 hollanderbart

@hollanderbart Did you found any solution for this issue. I am facing on this specifics. React Native 0.79.2 React-native-picker 2.11.0

udarakalpana avatar May 28 '25 13:05 udarakalpana

I tried finding a solution, but because the crash happens between React Native's hitTest and the library it's hard to resolve it (for now).

hollanderbart avatar May 29 '25 07:05 hollanderbart

In my case, I do

import { PickerIOS } from "@react-native-picker/picker";

And it looks no crash anymore.

jingp-ofload avatar Jun 02 '25 03:06 jingp-ofload

It is happening less indeed. Thanks for the suggestion @jingp-ofload

hollanderbart avatar Jun 04 '25 07:06 hollanderbart

Please this is critical, any fix for it?

@jingp-ofload is it the same as Picker? I’ll try that

janva255 avatar Jun 07 '25 12:06 janva255

I also saw this just today. Edit: I tried @jingp-ofload suggestion but it still fails, but with different error

Thread 1: EXC_BAD_ACCESS (code=1, address=0x20)

same as already mentioned issue #519

AnuragTiwari1 avatar Jun 11 '25 11:06 AnuragTiwari1

@Naturalclar Would you please want to look at the cause of these crashes on iOS?

hollanderbart avatar Jun 17 '25 15:06 hollanderbart

We experience the same issue. Seems more noticeable with more items in the picker. Maybe @vonovak has an idea how to fix this? 🤗

bobinrinder avatar Jun 25 '25 14:06 bobinrinder

@bobinrinder There are crashes with both Picker and PickerIOS, I suggest to move into a custom solution (it could be a flat list / legend list for more performance) until this is fixed.

janva255 avatar Jun 25 '25 14:06 janva255

on react native 0.80.0 also experiencing the crash. guess will have to use another picker

loekTheDreamer avatar Jun 26 '25 09:06 loekTheDreamer

Similar issue with many items here --- crash report


Translated Report (Full Report Below)

Hardware Model: Mac15,3 Process: Expo Go [52377] Identifier: host.exp.Exponent Version: 2.33.13 (2.33.13) Code Type: ARM-64 (Native) Role: Foreground Parent Process: launchd_sim [27584] Coalition: com.apple.CoreSimulator.SimDevice.6E68DCE3-B4A2-4CB3-984E-5145CA665239 [242734] Responsible Process: SimulatorTrampoline [27451]

Date/Time: 2025-06-26 08:51:46.0213 -0500 Launch Time: 2025-06-26 08:27:07.4261 -0500 OS Version: macOS 15.4.1 (24E263) Release Type: User Report Version: 104

Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000010 Exception Codes: 0x0000000000000001, 0x0000000000000010 VM Region Info: 0x10 is not in any region. Bytes before following region: 4329095152 REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL UNUSED SPACE AT START

Triggered by Thread: 0

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libobjc.A.dylib 0x18005f014 objc_msgSend + 20 1 UIKitCore 0x1855ec06c -[UITableView _updateVisibleCellsNow:] + 1112 2 UIKitCore 0x1855fc998 -[UITableView _visibleCellsUsingPresentationValues:] + 336 3 UIKitCore 0x1853b2298 -[UIPickerColumnView _allVisibleCells] + 48 4 UIKitCore 0x1853ba29c -[UIPickerView hitTest:withEvent:] + 244 5 Expo Go 0x1028a5270 -[RCTViewComponentView betterHitTest:withEvent:] + 496

ryan2625 avatar Jun 26 '25 16:06 ryan2625

Same problem here.

itsalysialynn avatar Jul 05 '25 22:07 itsalysialynn

I tried to solve the problem, but nothing works. https://github.com/quidone/react-native-wheel-picker is a good alternative. I've just test it, and replaced the picker by this package in my project.

IgorNoskov avatar Jul 14 '25 18:07 IgorNoskov

Does anyone have a solution? This issue is currently causing the most crashes in the production environment of my app.

huanguolin avatar Jul 22 '25 02:07 huanguolin

I got same problem. Who have any solution?

deepindive avatar Sep 15 '25 00:09 deepindive

@deepindive Hi, You can use this package npm i @react-native-community/datetimepicker

https://www.npmjs.com/package/@react-native-community/datetimepicker

udarakalpana avatar Sep 15 '25 02:09 udarakalpana

@huanguolin I have a some quetion. Did you put the picker inside the react-native-modal?

deepindive avatar Sep 15 '25 07:09 deepindive

@huanguolin I have a some quetion. Did you put the picker inside the react-native-modal?

Ah, I’m using the modal from React Native.

huanguolin avatar Sep 15 '25 12:09 huanguolin

@huanguolin Could you check your code for the Picker? I found some information, but I'm not sure about it. I heard that if you set the Picker's height to smaller than 216, it crashes. 216 is iOS Picker's Height.

deepindive avatar Sep 16 '25 01:09 deepindive

Still having issues. Might need to switch libraries if there is no plan to fix this.

itsalysialynn avatar Sep 24 '25 17:09 itsalysialynn

Same, I decided to uninstall and code our own picker, was causing too many issues.

chucklapointe avatar Sep 24 '25 17:09 chucklapointe

clicking the picker row quickly and continuously can reproduce the crash, update the picker only when the props value changes, fixed it in my project!

RNCPickerComponentView.mm

- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
{
    const auto &newProps = static_cast<const RNCPickerProps &>(*props);
    const auto &oldPickerProps = static_cast<const RNCPickerProps &>(*_props);
    
    // 比较并更新 items
    BOOL itemsChanged = NO;
    if (newProps.items.size() != oldPickerProps.items.size()) {
        itemsChanged = YES;
    } else {
        for (size_t i = 0; i < newProps.items.size(); i++) {
            const auto &newItem = newProps.items[i];
            const auto &oldItem = oldPickerProps.items[i];
            if (newItem.label != oldItem.label ||
                newItem.value != oldItem.value ||
                newItem.textColor != oldItem.textColor ||
                newItem.testID != oldItem.testID) {
                itemsChanged = YES;
                break;
            }
        }
    }
    
    if (itemsChanged) {
        NSMutableArray *items = [NSMutableArray new];
        for (RNCPickerItemsStruct item : newProps.items)
        {
            NSMutableDictionary *dictItem = [NSMutableDictionary new];
            dictItem[@"value"] = RNCPickerConvertFollyDynamicToId(item.value);
            dictItem[@"label"] = RNCPickerConvertFollyDynamicToId(item.label);
            dictItem[@"textColor"] = RCTUIColorFromSharedColor(item.textColor);
            dictItem[@"testID"] = RCTNSStringFromStringNilIfEmpty(item.testID);
            [items addObject:dictItem];
        }
        picker.items = items;
    }
    
    // 比较并更新 selectedIndex
    if (newProps.selectedIndex != picker.selectedIndex) { // 此处采用picker的selectedIndex比较,因为Native选中时会自动更新
        picker.selectedIndex = newProps.selectedIndex;
    }
    
    // 比较并更新 color
    if (newProps.color != oldPickerProps.color) {
        picker.color = RCTUIColorFromSharedColor(newProps.color);
    }
    
    // 比较并更新 textAlign (基于 themeVariant)
    NSString *newTextAlign = RCTNSStringFromStringNilIfEmpty(newProps.themeVariant);
    NSString *oldTextAlign = RCTNSStringFromStringNilIfEmpty(oldPickerProps.themeVariant);
    if (![newTextAlign isEqualToString:oldTextAlign]) {
        if ([newTextAlign isEqualToString:@"auto"]){
            picker.textAlign = NSTextAlignmentNatural;
        } else if ([newTextAlign isEqualToString:@"left"]){
            picker.textAlign = NSTextAlignmentLeft;
        } else if ([newTextAlign isEqualToString:@"center"]){
            picker.textAlign = NSTextAlignmentCenter;
        } else if ([newTextAlign isEqualToString:@"right"]){
            picker.textAlign = NSTextAlignmentRight;
        } else if ([newTextAlign isEqualToString:@"justify"]){
            picker.textAlign = NSTextAlignmentJustified;
        }
    }
    
    // 比较并更新 numberOfLines
    if (newProps.numberOfLines != picker.numberOfLines) { // 此处采用picker的numberOfLines比较
        picker.numberOfLines = newProps.numberOfLines;
    }
    
    // 比较并更新字体相关属性
    BOOL fontNeedsUpdate = NO;
    if (newProps.fontFamily != oldPickerProps.fontFamily ||
        newProps.fontSize != oldPickerProps.fontSize ||
        newProps.fontWeight != oldPickerProps.fontWeight ||
        newProps.fontStyle != oldPickerProps.fontStyle) {
        fontNeedsUpdate = YES;
    }
    
    if (fontNeedsUpdate) {
        picker.font = [RCTFont updateFont:picker.font 
                               withFamily:RCTNSStringFromStringNilIfEmpty(newProps.fontFamily) 
                                     size:@(newProps.fontSize) 
                                   weight:RCTNSStringFromStringNilIfEmpty(newProps.fontWeight) 
                                    style:RCTNSStringFromStringNilIfEmpty(newProps.fontStyle) 
                                  variant:nil 
                           scaleMultiplier:1];
    }
    
    // 比较并更新 themeVariant (用于 UserInterfaceStyle)
    if (@available(iOS 13.4, *)) {
        NSString *newThemeVariant = RCTNSStringFromStringNilIfEmpty(newProps.themeVariant);
        NSString *oldThemeVariant = RCTNSStringFromStringNilIfEmpty(oldPickerProps.themeVariant);
        if (![newThemeVariant isEqualToString:oldThemeVariant]) {
            if (newThemeVariant) {
                if ([newThemeVariant isEqual:@"dark"])
                    picker.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
                else if ([newThemeVariant isEqual:@"light"])
                    picker.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
                else
                    picker.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
            }
        }
    }
    
    [super updateProps:props oldProps:oldProps];
}

zhutc avatar Oct 09 '25 06:10 zhutc

clicking the picker row quickly and continuously can reproduce the crash, update the picker only when the props value changes, fixed it in my project!

RNCPickerComponentView.mm

- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
{
    const auto &newProps = static_cast<const RNCPickerProps &>(*props);
    const auto &oldPickerProps = static_cast<const RNCPickerProps &>(*_props);
    
    // 比较并更新 items
    BOOL itemsChanged = NO;
    if (newProps.items.size() != oldPickerProps.items.size()) {
        itemsChanged = YES;
    } else {
        for (size_t i = 0; i < newProps.items.size(); i++) {
            const auto &newItem = newProps.items[i];
            const auto &oldItem = oldPickerProps.items[i];
            if (newItem.label != oldItem.label ||
                newItem.value != oldItem.value ||
                newItem.textColor != oldItem.textColor ||
                newItem.testID != oldItem.testID) {
                itemsChanged = YES;
                break;
            }
        }
    }
    
    if (itemsChanged) {
        NSMutableArray *items = [NSMutableArray new];
        for (RNCPickerItemsStruct item : newProps.items)
        {
            NSMutableDictionary *dictItem = [NSMutableDictionary new];
            dictItem[@"value"] = RNCPickerConvertFollyDynamicToId(item.value);
            dictItem[@"label"] = RNCPickerConvertFollyDynamicToId(item.label);
            dictItem[@"textColor"] = RCTUIColorFromSharedColor(item.textColor);
            dictItem[@"testID"] = RCTNSStringFromStringNilIfEmpty(item.testID);
            [items addObject:dictItem];
        }
        picker.items = items;
    }
    
    // 比较并更新 selectedIndex
    if (newProps.selectedIndex != picker.selectedIndex) { // 此处采用picker的selectedIndex比较,因为Native选中时会自动更新
        picker.selectedIndex = newProps.selectedIndex;
    }
    
    // 比较并更新 color
    if (newProps.color != oldPickerProps.color) {
        picker.color = RCTUIColorFromSharedColor(newProps.color);
    }
    
    // 比较并更新 textAlign (基于 themeVariant)
    NSString *newTextAlign = RCTNSStringFromStringNilIfEmpty(newProps.themeVariant);
    NSString *oldTextAlign = RCTNSStringFromStringNilIfEmpty(oldPickerProps.themeVariant);
    if (![newTextAlign isEqualToString:oldTextAlign]) {
        if ([newTextAlign isEqualToString:@"auto"]){
            picker.textAlign = NSTextAlignmentNatural;
        } else if ([newTextAlign isEqualToString:@"left"]){
            picker.textAlign = NSTextAlignmentLeft;
        } else if ([newTextAlign isEqualToString:@"center"]){
            picker.textAlign = NSTextAlignmentCenter;
        } else if ([newTextAlign isEqualToString:@"right"]){
            picker.textAlign = NSTextAlignmentRight;
        } else if ([newTextAlign isEqualToString:@"justify"]){
            picker.textAlign = NSTextAlignmentJustified;
        }
    }
    
    // 比较并更新 numberOfLines
    if (newProps.numberOfLines != picker.numberOfLines) { // 此处采用picker的numberOfLines比较
        picker.numberOfLines = newProps.numberOfLines;
    }
    
    // 比较并更新字体相关属性
    BOOL fontNeedsUpdate = NO;
    if (newProps.fontFamily != oldPickerProps.fontFamily ||
        newProps.fontSize != oldPickerProps.fontSize ||
        newProps.fontWeight != oldPickerProps.fontWeight ||
        newProps.fontStyle != oldPickerProps.fontStyle) {
        fontNeedsUpdate = YES;
    }
    
    if (fontNeedsUpdate) {
        picker.font = [RCTFont updateFont:picker.font 
                               withFamily:RCTNSStringFromStringNilIfEmpty(newProps.fontFamily) 
                                     size:@(newProps.fontSize) 
                                   weight:RCTNSStringFromStringNilIfEmpty(newProps.fontWeight) 
                                    style:RCTNSStringFromStringNilIfEmpty(newProps.fontStyle) 
                                  variant:nil 
                           scaleMultiplier:1];
    }
    
    // 比较并更新 themeVariant (用于 UserInterfaceStyle)
    if (@available(iOS 13.4, *)) {
        NSString *newThemeVariant = RCTNSStringFromStringNilIfEmpty(newProps.themeVariant);
        NSString *oldThemeVariant = RCTNSStringFromStringNilIfEmpty(oldPickerProps.themeVariant);
        if (![newThemeVariant isEqualToString:oldThemeVariant]) {
            if (newThemeVariant) {
                if ([newThemeVariant isEqual:@"dark"])
                    picker.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
                else if ([newThemeVariant isEqual:@"light"])
                    picker.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
                else
                    picker.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
            }
        }
    }
    
    [super updateProps:props oldProps:oldProps];
}

you're right! I reproduced the crash clicking the picker row quickly and continuously. Your solution works. But if you have 2 picker on a screen and if unmount and mount the pickers the wheel will hide

vendeza avatar Oct 14 '25 21:10 vendeza

I'm using this patch and it seems to fix the crash @react-native-picker+picker+2.11.4.patch

vlad-lazovsky avatar Nov 03 '25 17:11 vlad-lazovsky

@zhutc would you be able to create a pr?

itsramiel avatar Nov 10 '25 12:11 itsramiel

shouldBeRecycled is a static method.

+ (BOOL)shouldBeRecycled
 {
     return NO;
 }

itsramiel avatar Nov 10 '25 13:11 itsramiel