RedMadRobot / input-mask-ios

User input masking library repo.
MIT License
578 stars 96 forks source link

Crash delegate #74

Closed AlexisQapa closed 5 years ago

AlexisQapa commented 5 years ago

Prerequisites

Describe the bug

I have a crash related to UITextView delegate. I'm not sure it's related to your library thought, I only use it with your library and the bug appeared in the same version I updated the library.

Here is a stack trace:

Fatal Exception: NSInvalidArgumentException 0 CoreFoundation 0x2329ca3a8 exceptionPreprocess 1 libobjc.A.dylib 0x231bcfd00 objc_exception_throw 2 CoreFoundation 0x2328e29f8 -[NSOrderedSet initWithSet:copyItems:] 3 CoreFoundation 0x2329cfd54 __forwarding 4 CoreFoundation 0x2329d1b50 _CF_forwarding_prep_0 5 UIKitCore 0x25ffdffc8 -[UITextView keyboardInputChangedSelection:] 6 UIKitCore 0x25ff518cc -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) notifyKeyboardSelectionChanged] 7 UIKitCore 0x25ff3c54c -[UITextNonEditableInteraction oneFingerTapInUneditable:] 8 UIKitCore 0x25f8ac420 -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] 9 UIKitCore 0x25f8b48e0 _UIGestureRecognizerSendTargetActions 10 UIKitCore 0x25f8b21dc _UIGestureRecognizerSendActions 11 UIKitCore 0x25f8b16b0 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] 12 UIKitCore 0x25f8a5474 _UIGestureEnvironmentUpdate 13 UIKitCore 0x25f8a4ba0 -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] 14 UIKitCore 0x25f8a4970 -[UIGestureEnvironment _updateForEvent:window:] 15 UIKitCore 0x25fcd7cac -[UIWindow sendEvent:] 16 UIKitCore 0x25fcb6f50 -[UIApplication sendEvent:] 17 UIKitCore 0x25fd82150 dispatchPreprocessedEventFromEventQueue 18 UIKitCore 0x25fd8490c handleEventQueueInternal 19 UIKitCore 0x25fd7d9c4 handleHIDEventFetcherDrain 20 CoreFoundation 0x23295a444 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION 21 CoreFoundation 0x23295a3c0 CFRunLoopDoSource0 22 CoreFoundation 0x232959c7c CFRunLoopDoSources0 23 CoreFoundation 0x232954950 CFRunLoopRun 24 CoreFoundation 0x232954254 CFRunLoopRunSpecific 25 GraphicsServices 0x234b93d8c GSEventRunModal 26 UIKitCore 0x25fc9c4c0 UIApplicationMain

Steps to reproduce the behaviour:

The crash happens rarely. Tried every gesture or input on all my textview ^^ as the stack trace doesn't contain any ref to my code.

Platform information

Additional context I use RxSwift/RxCocoa which can swizzle delegates thought each place I use this lib Rx is not used.

taflanidi commented 5 years ago

Hey @AlexisQapa, I'll take a look. Though I've got to clarify, how have you concluded it has to do with the delegate?

AlexisQapa commented 5 years ago

Indeed, over the stack I get : Fatal Exception: NSInvalidArgumentException -[RxCocoa.RxTextViewDelegateProxy keyboardInputChangedSelection:]: unrecognized selector sent to instance 0x280828620 So the delegate is indeed swizzled and it crash when forwarding the call to the delegate.

taflanidi commented 5 years ago

Holy cow, that's why I don't like those «fancy» Rx things, too much uncontrolled magic under the hood.

keyboardInputChangedSelection: is not a delegate selector, it is a part of the actual UITextView instance.

Long story short, long time ago, the NextStep delegate pattern assumed you were supposed to implement your delegates in a way that they would process all unrecognised selectors from the main object. Imagine you've got a UITextField instance upon which you call a random [textField abc]; selector — in this case your textField.delegate instance is supposed to answer the abc selector properly (a redirection from the textField instance).

My guess is, it looks like RxCocoa while overriding (swizzling) the UITextView had forgotten to address the keyboardInputChangedSelection: call, thus their "delegate proxy" throws and crashes.

I'll need more time to dig into this just in case, so please keep this issue open, though I don't think it has anything to do with our library.

AlexisQapa commented 5 years ago

Thanks for the input ! I'll open an issue on Rx repo.

AlexisQapa commented 5 years ago

I found something in my code that might be the cause. I'll close this while investigating

AlexisQapa commented 5 years ago

The bug was on my side. For anyone getting here from Google, I was indirectly setting a textview as its own delegate.