NSTextStorage 里面有长文本。表现
NSTextStorage with long text inside. Performance
我有一个 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 上需要 5 秒 20 秒 +
时间分析器显示,几乎所有时间都在获取 insertTextContainer 函数 (addTextContainer)。
有什么建议吗?
布局管理器在 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
您可以从最后一个文本容器索引开始保留或删除末尾的空文本容器。享受吧!
我有一个 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 上需要 5 秒 20 秒 +
时间分析器显示,几乎所有时间都在获取 insertTextContainer 函数 (addTextContainer)。
有什么建议吗?
布局管理器在 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
您可以从最后一个文本容器索引开始保留或删除末尾的空文本容器。享受吧!