我正在尝试设置UITextView的文本,其中包含一些非法字符,如“Unicode Character’OBJECT REPLACEMENT CHARACTER'(U FFFC)”.
基本上,我有一个UITextView.现在用户点击它并且键盘出现.现在我使用语音从键盘发送文本(也称为听写).当听写处理时(当时UITextView具有对应于默认占位符动画的特殊字符),我尝试使用以下方法设置文本视图的值:
基本上,我有一个UITextView.现在用户点击它并且键盘出现.现在我使用语音从键盘发送文本(也称为听写).当听写处理时(当时UITextView具有对应于默认占位符动画的特殊字符),我尝试使用以下方法设置文本视图的值:
textView.text = @""
这会造成以下崩溃:
*** Terminating app due to uncaught exception 'NSRangeException',reason: '-[__NSCFString replaceCharactersInRange:withString:]: Range or index out of bounds'
我从崩解剂中获得的堆栈跟踪:
0 CoreFoundation __exceptionPreprocess + 130 2 CoreFoundation -[NSException initWithCoder:] 3 CoreFoundation mutateError + 222 4 Foundation -[NSString stringByReplacingCharactersInRange:withString:] + 134 5 UIKit __37-[UITextInputController textInRange:]_block_invoke + 310 6 UIFoundation -[NSTextStorage coordinateReading:] + 36 7 UIKit -[UITextInputController textInRange:] + 232 8 UIKit -[TIDocumentState(UITextInputAdditions) _contextAfterPosition:inDocument:] + 190 9 UIKit -[TIDocumentState(UITextInputAdditions) initWithDocument:] + 150 10 UIKit +[TIDocumentState(UITextInputAdditions) documentStateOfDocument:] + 52 11 UIKit -[UIKeyboardImpl updateForChangedSelectionWithExecutionContext:] + 288 12 UIKit -[UIKeyboardTaskQueue continueExecutionOnMainThread] + 352 13 UIKit -[UIKeyboardTaskQueue performTask:] + 248 14 UIKit -[UIKeyboardImpl updateForChangedSelection] + 96 15 UIKit -[UIKeyboardImpl selectionDidChange:] + 102 16 UIFoundation -[NSTextStorage coordinateReading:] + 36 17 UIKit -[UITextInputController _coordinateSelectionChange:] + 100 18 UIKit -[UITextInputController _setSelectedTextRange:] + 604 19 UIKit -[UITextView setAttributedText:] + 392 20 UIKit -[UITextView setText:] + 134
我还创建了一个演示此问题的示例项目.你可以从https://dl.dropboxusercontent.com/u/80141854/TextViewDictationCheck.zip获得这个项目
可通过以下步骤复制例外:
>列表项目
>在xcode中运行项目.
>单击文本视图.键盘出现了.
>按键盘上的空格旁边的麦克风按钮.
>过了一段时间(4-5秒),按完成.
>现在,您将看到一个在textview中移动的微调器.当微调器在textview中移动时按send.
>你会得到例外.
我找到了一种避免崩溃的方法:
在设置UITextView的文本时,我们可以使用以下代码:
我还发现了一个在UITextView上重置文本时可以使用的解决方法:
[self.textView setSelectedRange:NSMakeRange(0,[[self.textView textStorage] length])]; [self.textView insertText:@""]; [self.textView setText:@""];
但是,如果我们只使用setText:来设置文本,我仍然没有理解这种崩溃的原因.
解决方法
基础代码中发生异常,而不是代码.如果在处理听写时更改了字符串,则存在导致此崩溃的竞争条件.当您触摸麦克风按钮时,它会将占位符放入字符串中,然后在完成处理时将其替换为文本.如果更改字符串并删除占位符,则会导致崩溃.
修复是为了确保在处理听写时不要更改字符串.您可以通过检查当前输入模式主要语言来执行此操作.当听写正在进行时,它将开始听写:
- (IBAction)sendPressed:(id)sender { NSString *primaryLanguage = [self.textView textInputMode].primaryLanguage; if(![primaryLanguage isEqualToString:@"dictation"]) { // Your original method body: NSString *textViewText = self.textView.text; textViewText = @""; self.textView.text = nil; self.textView.text = @""; }
}
如果正在进行听写,则会跳过代码以清空textview.