NSTextStorage里面有长文本。性能

时间:2018-03-26 16:46:05

标签: ios swift performance nstextstorage

我有一个NSTextStorage内部有长文本(例如一本书中的500页,当前字体的设备上超过9000)。我以这种方式为textcontainers分发此文本:

let textStorageLength = defaultTextStorage?.length ?? 0
while layoutManager!.textContainer(forGlyphAt: textStorageLength - 1, 
                                   effectiveRange: nil) == nil {
  let textContainer = NSTextContainer(size: textContainerSize)
  layoutManager!.addTextContainer(textContainer)
  pagesCount += 1
}

问题是初始化所有这些容器需要很长时间。我已经做了一些改进,比如改变代码使用

while lastRenderedGlyph < layoutManager!.numberOfGlyphs {

lastRenderedGlyph = NSMaxRange(layoutManager!.glyphRange(for: textContainer))

cz它的工作速度要慢得多。

那么,我可以做出哪些其他改进?在iPhone 7上,启动时间为7秒,在iPhone 5s上为20秒+

时间分析器显示,几乎所有时间都是获取insertTextContainer函数(addTextContainer)。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

布局管理器使addTextContainer方法调用上的布局无效,并在textContainer(forGlyphAt:effectiveRange:)上重建布局。您可以通过为布局管理器设置委托并观察layoutManagerDidInvalidateLayout来检查它。所以,然后做一次布局,你做了500次 - 每次添加文本容器一次。

您可以批量添加文本容器以减少布局数量,例如

  var lastTextConainer: NSTextContainer? = nil
  while nil == lastTextConainer {
     for _ in 1...100 {
       let textContainer = NSTextContainer(size: textContainerSize)
       layoutManager.addTextContainer(textContainer)
     }
     lastTextConainer = layoutManager.textContainer(forGlyphAt: layoutManager.numberOfGlyphs - 1, effectiveRange: nil)
  }
  let pagesCount = layoutManager.textContainers.index(of: lastTextConainer!)! + 1

最后的空文本容器可以从上一个文本容器索引开始离开或删除。享受!