临时文本属性导致大幅减速

时间:2008-12-14 21:17:41

标签: cocoa macos optimization

我使用我发布的代码作为this question的答案,在NSTextView中显示隐藏字符作为项目符号。

我使用addTemporaryAttributes:forCharacterRange:NSLayoutManager的方法为子弹着色。每个范围的长度为1,并且颜色为单个子弹。 (我使用的大多数相同的文字都有相对较少的相邻隐藏字符,尽管这是我计划在将来进行的优化。)

这种变化有许多不利影响。滚动文本视图变得缓慢而且不稳定,尤其是对于具有许多隐藏字符的文本。如何在不引起不可接受的性能影响的情况下为文本的部分着色?

1 个答案:

答案 0 :(得分:2)

滚动时出现最大影响的原因是,每次滚动视图滚动时,它都会重绘视图,并且通过扩展,会重新整理整个文档。因为,在单个滚动操作期间,滚动视图滚动了几个像素,向上或向下滚动n像素将重新着色整个文档n次!

我建议您确保只对屏幕上的文字进行着色。 想要做的最后一件事是将属性添加到已滚出视图的字符中,因为它在此时基本上浪费了周期。

您可以从文本视图中获取可见文本的范围:

- (NSRange)visibleRange
{
    NSRect visibleRect = [textView visibleRect];

    NSRange glyphVisibleRange = [[textView layoutManager] glyphRangeForBoundingRect:visibleRect inTextContainer:[textView textContainer]];
    NSRange charVisibleRange = [[textView layoutManager] characterRangeForGlyphRange:glyphVisibleRange  actualGlyphRange:nil];
    return charVisibleRange;
}

因此,当您进行着色时,只会着色落在此范围内的字形。这应该会使您的滚动性能提高几个数量级。