Найдите отличия:
Давайте-ка это обсудим.
Разберёмся подробнее, в каких именно ситуациях
- Текст может содержаться в следующих сущностях: UILabel, UITextView и UITextField
- В этих сущностях может использоваться обычная строка NSString и атрибутированная NSAttributedString
- Для строки мы можем получить символ рубля одним из трёх способов:
- Используя HTML:
NSString *htmlString = @"<p>500 ₽</p> "; self.string = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
- Используя unicode:
self.string = [[NSAttributedString alloc] initWithString: @"500 \u20BD"];
- Используя number formatter:
NSNumberFormatter * numberFormatter = [[NSNumberFormatter alloc] init]; [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; [numberFormatter setCurrencyCode:@"RUB"]; [numberFormatter setMaximumFractionDigits:0]; self.string = [[NSAttributedString alloc] initWithString:[numberFormatter stringFromNumber:@500]];
- Используя HTML:
Начав комбинировать сущности, я обнаружил, что производительность снижают следующие сочетания:
- UILabel, тип строки: attributed, методы получения символа: 2 или 3
- UITextView, тип строки: любой, методы получения символа: любой
- UITextField, тип строки: любой, методы получения символа: любой
Эксперимент заключался в измерении нагрузки на процессор при пролистывании списка, элементы которого содержали символ рубля. Средняя нагрузка на процессор для нормального состояния не превышала 10%, а если была проблема, нагрузка колебалась в районе 30-80%, что можно видеть на гифках.
На картинке обведены символы, с которыми наблюдается описанная проблема.
Чтобы приложение вело себя нормально, нужно избегать тех сочетаний, что я выявил, или использовать для символов валют системный шрифт San Francisco, а также шрифты из семейства Helvetica Neue. Но это минимальные требования. Истинная же причина увеличения нагрузки для меня осталась загадкой, и если кто-то разбирается в сути вопроса — делитесь соображениями в комментариях.
Комментарии (9)
Pr0Ger
15.11.2016 14:11+3Ковырял этот баг в сентябре (ибо такое поведение проявилось только на десятке). Судя по профайлеру корень проблемы в том что размер такого символа считается очень долго. И кстати у меня воспроизводилось и на UILabel с не attributed строкой с Helvetica Neue
Что то типа такого в конечно итоге выходитsvistkovr
15.11.2016 15:01+3— Вообще-то UITextView/UITextField это поля для редактирования текста и они отлавливают обработку нажатий
— Вы используете NSAttributedString. Этот класc используется для вывода текста со стилями.
Попробуйте использовать:
— UILabel с простыми строками NSString
— Можно попробовать через чистый CoreText делать выводsvistkovr
15.11.2016 15:06+2P.S.
Еще стоит проверить как вы формируете таблицу. Возможно в делегатах таблиц понапихано много всего.
Тестирование стоит проводить на реальном устройстве. Симулятор привязан к железу вашего компа и может давать неверные результаты измерений.MaiorPro
16.11.2016 09:16Попробуйте использовать:
Для наших задач необходимо было использование стилей и обычная строка не подходит
— UILabel с простыми строками NSString
— Можно попробовать через чистый CoreText делать вывод
Стоит попробовать
P.S.
В методах делегата для приведенного примера используется только указание высоты для строки. Описанная проблема не связана с вызовом методов делегирования
Еще стоит проверить как вы формируете таблицу. Возможно в делегатах таблиц понапихано много всего.
Тестирование стоит проводить на реальном устройстве. Симулятор привязан к железу вашего компа и может давать неверные результаты измерений.
Тестирование проводилось в том числе и на реальном устройстве и соответствует результатам проведенным на симуляторе
MaiorPro
16.11.2016 08:55Неправильно было построено предложение, исправил. Речь была о том, что независимо от сущности содержащей текст проблема будет актуальна
destman
17.11.2016 16:04Если в вашем кастомном шрифте много глифов возможно проблема в поиске нужного глифа при подготовке текста к рендерингу.
Проверить что именно в этом проблема — замерять сколько времени работает CTLineCreateWithAttributedString с соответствующей строкой.
Если в глиф плохо оптимизирован (дизайнер натыкал 100500 точек) — то тоже может быть проблема в расчетах границ глифа (примерно чекнуть можно юзая CTLineGetImageBounds) + сама прорисовка может быть не быстрая (CTFontDrawGlyphs)…
slutsker
20.11.2016 02:26Столкнулся с резким увеличением потребления ресурсов и медленной загрузкой приложения. После профайлинга заметил, что дело в нестандартных шрифтах, добавленных в проект. После перехода на системные шрифты, приложение стало гораздо быстрее работать.
AllexIn
А вы пробовали посмотреть, как нарисован символ в используемом шрифте? Может быть там ад из 100500 сплайнов?