Undo crash with multiple conditionally rendered TextEditor views

157 views Asked by At

Running the code below in macOS simulator (macOS 12.5.1, Xcode 14.0), I can reproduce an undo-related crash:

  1. Click the "Edit first" button
  2. Edit the (first) input to e.g. "helloo"
  3. Click the "Edit second" button
  4. Click "Undo" in the "Edit" menu, or use the shortcut Cmd + Z.

What I expect to happen: Nothing (second input was not changed, first TextEditor is not rendered any more)

What actually happens: The app crashes with message Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)

Is it a bug, or e.g. shall I explicitly clean up the first input from "undo history" when the view disappears?

import SwiftUI

@main
struct MacosPlaygroundApp: App {
    var body: some Scene {
        WindowGroup("Playground") {
            TextEditors()
                .frame(width: 700, height: 300, alignment: .center)
        }
    }
}

struct TextEditors: View {

    @State private var edited: Edited = .none
    @State private var input1: String = "hello"
    @State private var input2: String = "world"

    @FocusState private var focused1: Bool
    @FocusState private var focused2: Bool

    var body: some View {
        Button("Edit none") { edited = .none }
        Button("Edit first") { edited = .first }
        Button("Edit second") { edited = .second }

        if case .first = edited {
            TextEditor(text: $input1)
                .focused($focused1)
                .onAppear { Task { focused1 = true } }
        }

        if case .second = edited {
            TextEditor(text: $input2)
                .focused($focused2)
                .onAppear { Task { focused2 = true } }
        }
    }

    private enum Edited {
        case none
        case first
        case second
    }
}

Error details

I re-ran it several times. There are two possible outcomes:

  1. Most of the time, this is what happens:
    • Next to @main, a message Thread 1: EXC_BAD_ACCESS (code=1, address=0x5fdaa4174c7758) (the address varies)
    • In the console, there is an lldb prompt. The output for po [$arg1 reason] is:
error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression
  1. A few times, it does not crash, but shows this in the console:
2022-09-24 20:30:47.236018+0200 MacosPlayground[13230:380687] Metal API Validation Enabled
2022-09-24 20:30:54.489970+0200 MacosPlayground[13230:380687] -[_CUIInternalLinkRendition _undoRedoTextOperation:]: unrecognized selector sent to instance 0x129798880
2022-09-24 20:30:54.490397+0200 MacosPlayground[13230:380687] [General] An uncaught exception was raised
2022-09-24 20:30:54.490457+0200 MacosPlayground[13230:380687] [General] -[_CUIInternalLinkRendition _undoRedoTextOperation:]: unrecognized selector sent to instance 0x129798880
2022-09-24 20:30:54.495192+0200 MacosPlayground[13230:380687] [General] (
    0   CoreFoundation                      0x000000018eb5d1a8 __exceptionPreprocess + 240
    1   libobjc.A.dylib                     0x000000018e8a7e04 objc_exception_throw + 60
    2   CoreFoundation                      0x000000018ebf0f4c -[NSObject(NSObject) __retain_OA] + 0
    3   CoreFoundation                      0x000000018eabc554 ___forwarding___ + 1764
    4   CoreFoundation                      0x000000018eabbdb0 _CF_forwarding_prep_0 + 96
    5   Foundation                          0x000000018fa92458 -[_NSUndoStack popAndInvoke] + 180
    6   Foundation                          0x000000018fa92190 -[NSUndoManager undoNestedGroup] + 292
    7   AppKit                              0x00000001918465c8 -[NSApplication(NSResponder) sendAction:to:from:] + 460
    8   AppKit                              0x000000019193c2ec -[NSMenuItem _corePerformAction] + 444
    9   AppKit                              0x000000019193bfe0 -[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] + 100
    10  AppKit                              0x0000000191984bd8 -[NSMenu performActionForItemAtIndex:] + 200
    11  AppKit                              0x0000000191984af8 -[NSMenu _internalPerformActionForItemAtIndex:] + 100
    12  AppKit                              0x0000000191984904 -[NSCarbonMenuImpl _carbonCommandProcessEvent:handlerCallRef:] + 116
    13  AppKit                              0x000000019191fe70 NSSLMMenuEventHandler + 728
    14  HIToolbox                           0x00000001976f26c8 _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 1084
    15  HIToolbox                           0x00000001976f1b4c _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 356
    16  HIToolbox                           0x0000000197707e50 SendEventToEventTarget + 40
    17  HIToolbox                           0x0000000197768870 _ZL18SendHICommandEventjPK9HICommandjjhPKvP20OpaqueEventTargetRefS5_PP14OpaqueEventRef + 416
    18  HIToolbox                           0x000000019778d9ac SendMenuCommandWithContextAndModifiers + 56
    19  HIToolbox                           0x000000019778d93c SendMenuItemSelectedEvent + 352
    20  HIToolbox                           0x000000019778d768 _ZL19FinishMenuSelectionP13SelectionDataP10MenuResultS2_ + 100
    21  HIToolbox                           0x000000019778e128 _ZL14MenuSelectCoreP8MenuData5PointdjPP13OpaqueMenuRefPt + 560
    22  HIToolbox                           0x000000019778de48 _HandleMenuSelection2 + 416
    23  AppKit                              0x00000001917df6f0 _NSHandleCarbonMenuEvent + 300
    24  AppKit                              0x00000001917df4d0 _DPSEventHandledByCarbon + 68
    25  AppKit                              0x00000001916415b4 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 3280
    26  AppKit                              0x0000000191632fe0 -[NSApplication run] + 596
    27  AppKit                              0x00000001916046fc NSApplicationMain + 1132
    28  SwiftUI                             0x00000001b4059e98 $s7SwiftUI6runAppys5NeverOSo21NSApplicationDelegate_So11NSResponderCXcFTf4e_nAA07TestingdG0C_Tg5 + 148
    29  SwiftUI                             0x00000001b4be8588 $s7SwiftUI6runAppys5NeverOxAA0D0RzlF + 260
    30  SwiftUI                             0x00000001b465e26c $s7SwiftUI3AppPAAE4mainyyFZ + 128
    31  MacosPlayground                     0x0000000100d4941c $s15MacosPlayground0aB3AppV5$mainyyFZ + 40
    32  MacosPlayground                     0x0000000100d4c07c main + 12
    33  dyld                                0x000000010108908c start + 520
0

There are 0 answers