textViewDidChange:在iOS 7中崩溃 [英] textViewDidChange: crashes in iOS 7

查看:836
本文介绍了textViewDidChange:在iOS 7中崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们知道 UITextView 在iOS 7中更强大,但在这里它表现得更加脆弱。在iOS 6中使用中文输入键盘输入rr时,以下代码正常工作,但在iOS 7中崩溃。

As we know the UITextView is more powerful in iOS 7, but here it performs more fragile. The following code works fine when inputting "rr" with Chinese input keyboard in iOS 6, but crashes in iOS 7.

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.tv = [[UITextView alloc] initWithFrame:CGRectMake(0, 100, 320, 100)];
    self.tv.backgroundColor = [UIColor yellowColor];
    self.tv.textColor = [UIColor blackColor];
    self.tv.editable = YES;
    self.tv.delegate = self;

    [self.view addSubview:self.tv];
}

-(void)textViewDidChange:(UITextView *)textView{

    int maxLength = 2;
    if (self.tv.text.length > maxLength) {
        NSLog(@"self.tv.text :%@",self.tv.text);
        NSLog(@"self.tv.text.length :%d",self.tv.text.length);
        NSLog(@"maxLength :%d",maxLength);
        self.tv.text = [self.tv.text substringToIndex:maxLength];
    }
}

日志如下:

2013-11-13 15:48:16.003 Test2[1388:70b] self.tv.text :r r
2013-11-13 15:48:16.004 Test2[1388:70b] self.tv.text.length :3
2013-11-13 15:48:16.005 Test2[1388:70b] maxLength :2
2013-11-13 15:48:16.032 Test2[1388:70b] *** Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds'
*** First throw call stack:
(
    0   CoreFoundation                      0x017355e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x014b88b6 objc_exception_throw + 44
    2   CoreFoundation                      0x017353bb +[NSException raise:format:] + 139
    3   Foundation                          0x010ebba1 -[NSMutableRLEArray replaceObjectsInRange:withObject:length:] + 136
    4   Foundation                          0x010ebb14 -[NSMutableRLEArray deleteObjectsInRange:] + 63
    5   Foundation                          0x010ea559 -[NSConcreteMutableAttributedString replaceCharactersInRange:withAttributedString:] + 324
    6   UIFoundation                        0x02d9d9f4 __71-[NSConcreteTextStorage replaceCharactersInRange:withAttributedString:]_block_invoke + 68
    7   UIFoundation                        0x02d9d92f -[NSConcreteTextStorage replaceCharactersInRange:withAttributedString:] + 121
    8   UIKit                               0x00924d22 __53-[UITextInputController setMarkedText:selectedRange:]_block_invoke + 352
    9   UIFoundation                        0x02d9b491 -[NSTextStorage coordinateEditing:] + 48
    10  UIKit                               0x00924a38 -[UITextInputController setMarkedText:selectedRange:] + 249
    11  UIKit                               0x008fb3b1 -[UITextView setMarkedText:selectedRange:] + 63
    12  UIKit                               0x00644aa5 -[UIResponder(UITextInput_Internal) _setMarkedText:selectedRange:] + 101
    13  UIKit                               0x004031aa -[UIKeyboardImpl setMarkedText:selectedRange:inputString:searchString:] + 365
    14  UIKit                               0x00419737 -[TIKeyboardOperationSetMarkedText(UIKeyboardImpl) main] + 178
    15  Foundation                          0x0118da69 -[__NSOperationInternal _start:] + 671
    16  Foundation                          0x0110a798 -[NSOperation start] + 83
    17  UIKit                               0x0040e08a -[UIKeyboardImpl updateCandidateDisplayAsyncWithCandidateSet:documentOperation:] + 188
    18  UIKit                               0x00419041 -[TIKeyboardOperationSetCandidates(UIKeyboardImpl) main] + 112
    19  Foundation                          0x0118da69 -[__NSOperationInternal _start:] + 671
    20  Foundation                          0x0110a798 -[NSOperation start] + 83
    21  UIKit                               0x0040671d -[UIKeyboardImpl performOperations:] + 153
    22  UIKit                               0x00404f4e -[UIKeyboardImpl continueGenerateCandidatesAsynchronouslyWithOperations:] + 40
    23  UIKit                               0x00404c51 __87-[UIKeyboardImpl replyHandlerForGenerateCandidatesAsynchronouslyWithSelectedCandidate:]_block_invoke_2 + 46
    24  UIKit                               0x009381b8 -[UIKeyboardTaskQueue continueExecutionOnMainThread] + 402
    25  UIKit                               0x0093885f -[UIKeyboardTaskQueue addTask:] + 144
    26  CoreFoundation                      0x01729d1d __invoking___ + 29
    27  CoreFoundation                      0x01729c2a -[NSInvocation invoke] + 362
    28  UIKit                               0x008e63d2 -[_UIActionWhenIdle invoke] + 100
    29  UIKit                               0x008e64a6 __41-[_UIActionWhenIdle addObserverToRunLoop]_block_invoke + 36
    30  CoreFoundation                      0x0172924d _runLoopObserverWithBlockContext + 29
    31  CoreFoundation                      0x016fd53e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
    32  CoreFoundation                      0x016fd48f __CFRunLoopDoObservers + 399
    33  CoreFoundation                      0x016db3b4 __CFRunLoopRun + 1076
    34  CoreFoundation                      0x016dab33 CFRunLoopRunSpecific + 467
    35  CoreFoundation                      0x016da94b CFRunLoopRunInMode + 123
    36  GraphicsServices                    0x036d69d7 GSEventRunModal + 192
    37  GraphicsServices                    0x036d67fe GSEventRun + 104
    38  UIKit                               0x0022b94b UIApplicationMain + 1225
    39  Test2                               0x0000388d main + 141
    40  libdyld.dylib                       0x01d7370d start + 1
    41  ???                                 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

另外,我测试下面的代码,用中文输入键盘输入rr后也会崩溃。

In addition, I test the following code, it also crashes after input "rr" with Chinese input keyboard.

-(void)textViewDidChange:(UITextView *)textView{

    int maxLength = 2;
    if (self.tv.text.length > maxLength) {
        self.tv.text = @"c";
    }
}

任何帮助将不胜感激!

推荐答案

正在发生的事情是您正在键入所谓的多级文本输入,即输入必须是在用户实际提交到基础文本之前从用户确认。你得到了崩溃,因为文本只是一种输入,在文本提交之前,它很容易变成其他东西。

What's happening is that you're typing what is referred to as multistage text input, i.e. the input has to be confirmed from the user before it's actually committed into the underlying text. You get the crash because the text is only kind-of inputted, and until the text has been committed, it could easily change to something else.

要检测这种情况,您正在寻找 markedTextRange 属性,表示您是否处于这种复杂的输入模式。

To detect this situation, you're looking for the markedTextRange property of the UITextView, which indicates if you're in this complex input mode.

如果属性是非零的,那么你处于这种特殊的输入模式,所以你应该用以下的方式保护你的修改代码:

If the property is non-nil, then you're in this special input mode, so you should guard your modification code with something like:

if (self.tv.markedTextRange == nil && self.tv.text.length > maxLength) {
    // Perform change
}

我可以告诉崩溃是由特殊的多级文本输入模式触发的,所以你应该避免在这种模式下更改文本是活跃的。

Near as I can tell the crash is triggered by the special multistage text input mode, so you should avoid changing the text while this mode is active.

这篇关于textViewDidChange:在iOS 7中崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆