UITextView冻结了来自textViewShouldBeginEditing的iPad应用程序。 (无效的字形索引)

时间:2015-11-02 16:00:23

标签: ios objective-c ipad uitextview freeze

所以我一直在研究这个bug大约一个星期,而对于我的生活,我无法弄清楚发生了什么。

由于机密性问题,我无法发布太多代码,但我会尽力解释所有内容。

我们正在通过代码填充UITextField,并且最初将文本显示为灰色。然后,用户可以执行以下两项操作之一:

1)点击一个显示“commit”的按钮,调用一个方法,该方法执行以下方法,我们称之为“commitData”。它执行以下操作:

  1. 使用撤消管理器
  2. 注册提交
  3. 将文字从灰色更改为黑色
  4. 向我们的应用程序注册文本字段已更新,需要在申请结束时保存
  5. 2)点击带有灰色文本的文本字段,然后调用以下默认的apple方法textViewShouldBeginEditing。从这里我们调用我们在选项1中列出的“commitData”方法,如下所示:

    -(BOOL)textViewShouldBeginEditing:(UITextView *)textView
    {
        if ([[self box] hasGreyedOutText])
            [[self box] commitData];
    
        [self setActiveTextView:textView];
        return YES;
    }
    

    我们遇到的问题是点击按钮提交灰色文本非常合适,我们遇到了问题。

    无论其

    当我们点击文本字段并触发textViewShouldBeginEditing方法时,我们的iPad会冻结并让用户等待几分钟才能完成。当我的意思是冻结时,我的意思是整个iPad冻结。发生这种情况时,iPad时钟甚至不会更新。

    当发生这种情况时,我们会在控制台中收到错误代码:

    !!! _NSLayoutTreeLineFragmentRectForGlyphAtIndex invalid glyph index 2147483647
    

    我们可以按照上述步骤从上面的所有硬件中获取上面的错误代码,但只能在iPad 2上重现冻结(但准确度为100%)。

    • 关于这一点的说明,我的同事通过诊断发现,当发生此错误时,我们只有大约8MB的可用RAM。然而,我们只在iPad 2上打过这么小的内存,所以这可能只是巧合。

    我有一种感觉,这可能与线程有关,我们可能需要在从textViewShouldBeginEditing方法返回YES之后以某种方式调用我们的方法,但我不太确定我应该怎么做。

    如果有人对如何解决这个问题有任何想法,或者甚至是能够指出我正确方向的想法,我将非常感激。我到处都看到了我能想到的,而且我找到的与错误代码相关的解决方案都没有结束。

1 个答案:

答案 0 :(得分:3)

我无法调试,所以在我猜中它可能是由非主线程UI操作引起的。所以,我的建议是确保您的UI代码在mainThread中。试试这个:

-(BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
    dispatch_async(dispatch_get_main_queue(), ^{ 
    if ([[self box] hasGreyedOutText])
        [[self box] commitData];
    [self setActiveTextView:textView];
    }
    return YES;
}