简体   繁体   中英

iOS out of range crash when using shake to undo a paste into UITextView with overwritten shouldChangeCharactersInRange

My iOS application is crashed and I have the crash report but I cannot figure out the reason for crashing. The strange part is that this crashed has happened a little bit after application start and there is no indication of my code in crash report:

Thread 0 Crashed:
0   CoreFoundation                  0x00000002069d0ea4 __exceptionPreprocess + 228
1   libobjc.A.dylib                 0x0000000205ba0a50 objc_exception_throw + 56
2   CoreFoundation                  0x00000002068d7484 -[NSCache init] + 0
3   Foundation                      0x0000000207355b94 -[NSString substringWithRange:] + 140
4   UIKitCore                       0x00000002331cd8b8 -[NSTextStorage+ 12540088 (UIKitUndoExtensions) _undoRedoAttributedSubstringFromRange:] + 152
5   UIKitCore                       0x00000002331ce808 -[_UITextUndoOperationTyping undoRedo] + 340
6   Foundation                      0x00000002073f6734 -[_NSUndoStack popAndInvoke] + 280
7   Foundation                      0x00000002073f4790 -[NSUndoManager undoNestedGroup] + 416
8   UIKitCore                       0x0000000232ed1824 __58-[UIApplication _showEditAlertViewWithUndoManager:window:]_block_invoke.2529 + 32
9   UIKitCore                       0x0000000232618a58 -[UIAlertController _invokeHandlersForAction:] + 108
10  UIKitCore                       0x000000023261941c __103-[UIAlertController _dismissAnimated:triggeringAction:triggeredByPopoverDimmingView:dismissCompletion:]_block_invoke.477 + 28
11  UIKitCore                       0x0000000232821784 -[UIPresentationController transitionDidFinish:] + 1320
12  UIKitCore                       0x0000000232825794 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke.440 + 188
13  UIKitCore                       0x0000000232923714 -[_UIViewControllerTransitionContext completeTransition:] + 116
14  UIKitCore                       0x000000023335cc4c -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 744
15  UIKitCore                       0x00000002333328f0 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 312
16  UIKitCore                       0x0000000233332edc -[UIViewAnimationState animationDidStop:finished:] + 296
17  UIKitCore                       0x0000000233332f7c -[UIViewAnimationState animationDidStop:finished:] + 456
18  QuartzCore                      0x000000020afde500 CA::Layer::run_animation_callbacks+ 1381632 (void*) + 284
19  libdispatch.dylib               0x0000000206409484 _dispatch_client_callout + 16
20  libdispatch.dylib               0x00000002063b59a4 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1068
21  CoreFoundation                  0x0000000206960ce4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
22  CoreFoundation                  0x000000020695bbac __CFRunLoopRun + 1964
23  CoreFoundation                  0x000000020695b0e0 CFRunLoopRunSpecific + 436
24  GraphicsServices                0x0000000208bd4584 GSEventRunModal + 100
25  UIKitCore                       0x0000000232ec0c00 UIApplicationMain + 212
26  MyApplication                   0x00000001009489fc main (main.m:17)
27  libdyld.dylib                   0x0000000206419bb4 start + 4

Steps to Reproduce:

  • Implement an app with a UITextField
  • Implement the UITextFieldDelegate protocol and assign the UITextField delegate
  • Implement the -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string method Return NO from that method
  • Run app and attempt to paste text into the UITextField and observe that no text is actually pasted
  • Shake the phone to trigger the Undo prompt
  • Tap the Undo button in the prompt and observe crash

Any help will be appreciated

If text for UITextView or UITextField is changed programatically while it is being changed the undo manager would not be updated and will keep track of wrong actions. To avoid crash we should reset undo manager so it does not contain dirty actions.

[textField.undoManager removeAllActions];

If anyone is still facing this crash, try to set this as the custom class for textView.

class MessageTextView: UITextView {
override var attributedText: NSAttributedString? {
    didSet {
        self.undoManager?.removeAllActions()
    }
}

override var text: String? {
    didSet {
        self.undoManager?.removeAllActions()
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM