【问题标题】:Temporary text attributes causing massive slowdown导致大幅减速的临时文本属性
【发布时间】:2008-12-14 21:17:41
【问题描述】:

我正在使用我作为@​​987654321@ 的答案发布的代码将 NSTextView 中的隐藏字符显示为项目符号。

我使用 NSLayoutManager 的 addTemporaryAttributes:forCharacterRange: 方法将项目符号着色为灰色。每个范围的长度为 1,并为单个项目符号着色。 (我使用的大部分相同文本的相邻隐藏字符相对较少,尽管这是我计划在未来进行的优化。)

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

【问题讨论】:

    标签: cocoa macos optimization


    【解决方案1】:

    滚动时最大的打击是因为每次滚动视图滚动时,它都会重绘视图,进而重新着色整个文档。因为,在单次滚动操作期间,滚动视图滚动了几个像素,只需向上或向下滚动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;
    }
    

    因此,当您进行着色时,请仅对处于此范围内的字形进行着色。这应该会将您的滚动性能提高几个数量级。

    【讨论】:

    • 为什么-drawGlyphsForGlyphRange:atPoint: 的第一个参数不是可见范围?
    • 我认为这实际上减慢了进程;显然 -drawGlyphsForGlyphRange:atPoint: 只返回需要重绘的范围,不一定是整个可见范围。 (虽然我可能会误解这一点。)
    猜你喜欢
    • 2018-09-23
    • 2014-03-30
    • 2016-05-20
    • 1970-01-01
    • 2018-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多