網站首頁 編程語言 正文
正文
在適配iOS13的過程中,UITextField
輸入中文的時候三指撤銷產生了 crash。
Bugly報錯
NSInternalInconsistencyException setGroupIdentifier:: _NSUndoStack 0x1206532f0 is in invalid state, calling setGroupIdentifier with no begin group mark
堆棧信息
CoreFoundation ___exceptionPreprocess + 220 libobjc.A.dylib objc_exception_throw + 56 Foundation -[_NSUndoStack groupIdentifier] Foundation -[NSUndoManager undoNestedGroup] + 240 UIKitCore -[UIUndoGestureInteraction undo:] + 72 UIKitCore -[UIKBUndoInteractionHUD performDelegateUndoAndUpdateHUDIfNeeded] + 96 UIKitCore -[UIKBUndoInteractionHUD controlActionUpInside:] + 152 UIKitCore -[UIApplication sendAction:to:from:forEvent:] + 96 xxxxx -[UIApplication(MemoryLeak) swizzled_sendAction:to:from:forEvent:] + 288 UIKitCore -[UIControl sendAction:to:forEvent:] + 240 UIKitCore -[UIControl _sendActionsForEvents:withEvent:] + 408 UIKitCore -[UIControl touchesEnded:withEvent:] + 520 UIKitCore -[UIWindow _sendTouchesForEvent:] + 2324 UIKitCore -[UIWindow sendEvent:] + 3352 UIKitCore -[UIApplication sendEvent:] + 336 UIKitCore ___dispatchPreprocessedEventFromEventQueue + 5880 UIKitCore ___handleEventQueueInternal + 4924 UIKitCore ___handleHIDEventFetcherDrain + 108 CoreFoundation ___CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24 CoreFoundation ___CFRunLoopDoSource0 + 80 CoreFoundation ___CFRunLoopDoSources0 + 180 CoreFoundation ___CFRunLoopRun + 1080 CoreFoundation CFRunLoopRunSpecific + 464 GraphicsServices GSEventRunModal + 104 UIKitCore UIApplicationMain + 1936 xxxxx main + 148 libdyld.dylib _start + 4
問題定位
沒有太多思路的時候,通過注釋代碼,最終定位到了問題所在。
[self addTarget:observer action:@selector(textChange:) forControlEvents:UIControlEventEditingChanged];
- (void)textChange:(UITextField *)textField { ... ... UITextRange *selectedRange = [textField markedTextRange]; if (!selectedRange || !selectedRange.start) { if (destText.length > maxLength) { textField.text = [destText substringToIndex:maxLength]; } } }
這段代碼在輸入的時候會限制文案的長度。三指撤銷會觸發UIControlEventEditingChanged
事件,執行textChange
,此時獲取到的markedTextRange
是nil
,即便是存在markedText
。這就導致UITextField
的text
有可能會被修改。修改文案后再繼續執行撤銷操作,必定會產生 crash。
解決方案
將文案判長和截取異步添加到主隊列,在下一個runloop
執行。
- (void)textChange:(UITextField *)textField { dispatch_async(dispatch_get_main_queue(), ^{ ... ... }); }
數字截斷后 crash
數字輸入限制長度后,超過長度后繼續輸入,這個時候撤銷也會產生crash,而且上面的方法不可行。目前想到的方案是在UITextField
的回調方法進行輸入的攔截。
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { /// 輸入數字后截取字符串仍舊可以觸發撤銷操作導致crash, 在這里攔截一下 if (textField.keyboardType == UIKeyboardTypeNumberPad && range.location >= textField.tt_maxLength) { return NO; } return YES; }
原文鏈接:https://juejin.cn/post/6844903952526344205
相關推薦
- 2023-06-03 Django使用jinja2模板的實現_python
- 2022-11-30 React之錯誤邊界?Error?Boundaries示例詳解_React
- 2022-06-13 ASP.NET?Core使用自定義日志中間件_實用技巧
- 2022-05-03 C#面向對象設計原則之組合/聚合復用原則_C#教程
- 2022-12-08 Apache?Cordova?Android原理應用實例詳解_Android
- 2023-02-01 Python局部函數及用法詳解(含nonlocal關鍵字)_python
- 2022-01-22 linux系統raid0測試實驗
- 2022-03-20 關于Rancher部署并導入K8S集群的問題_云其它
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支