NSTextStorage с длинным текстом внутри. Спектакль
У меня есть NSTextStorage
с длинным текстом внутри (например, 500 страниц в книге и более 9000 на устройстве для текущего шрифта). Я распространяю этот текст для текстовых контейнеров следующим образом:
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 ответ
Менеджер макетов делает недействительным макет на 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
Пустые текстовые контейнеры в конце вы можете оставить или удалить, начиная с последнего индекса текстового контейнера. Наслаждайтесь!