Що не так з відображенням символів валют в iOS

У червні 2016 року в App Store з'явився додаток розроблене нами ІЛЬ ДЕ БОТЭ. Клієнт попросив нас використовувати шрифт Carisma. До системних шрифтів платформи iOS він не відноситься, що можна зрозуміти після спроби знайти його тут. Працюючи над додатком, я зазначив, що символи валют, що потрапляють в діапазон від U+20B6 (символ турського ливра) до U+20BE (символ грузинського ларі) і набрані шрифтом, що не входять до числа системних, знижують продуктивність програми. Символ рубля — як раз з зазначеного діапазону.

Знайдіть відмінності:



Капітан виходить на зв'язокЕкран праворуч лагает. Це помітно за показником завантаженості CPU.

Давайте це обговоримо.

Розберемося детальніше, в яких саме ситуаціях всі гальмує знижується продуктивність. Для цього розіб'ємо подання рядка з символом валюти на складові частини:

  1. Для відображення використовуються наступні сутності: UILabel, UITextView і UITextField
  2. У цих сутності використовуються звичайна рядок NSString і атрибутированная NSAttributedString
  3. Для рядка ми можемо отримати символ рубля одним з трьох способів:

    1. Використовуючи HTML:

      NSString *htmlString = @"<p>500 ₽</p> ";
      self.string = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
      


    2. Використовуючи unicode:

      self.string = [[NSAttributedString alloc] initWithString: @"500 \u20BD"];
      

    3. Використовуючи number formatter:

      NSNumberFormatter * numberFormatter = [[NSNumberFormatter alloc] init];
      [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
      [numberFormatter setCurrencyCode:@"RUB"];
      [numberFormatter setMaximumFractionDigits:0];
      self.string = [[NSAttributedString alloc] initWithString:[numberFormatter stringFromNumber:@500]];
      
Почавши комбінувати суті, я виявив, що знижують продуктивність наступні поєднання:

  1. UILabel, тип рядка: attributed, методи отримання символу: 2 або 3
  2. UITextView, тип рядка: будь, методи отримання символу: будь
  3. UITextField, тип рядка: будь, методи отримання символу: будь
Експеримент полягав у вимірюванні навантаження на процесор при перегляду списку, елементи якого містили символ рубля. Середнє навантаження на процесор для нормального стану не перевищувала 10%, а якщо була проблема, навантаження коливалася в межах 30-80%, що можна бачити на гіфці.

Щоб додаток вело себе нормально, потрібно уникати тих поєднань, що я виявив, або використовувати для символів валют системний шрифт San Francisco, а також шрифти з сімейства Helvetica Neue. Але це мінімальні вимоги. Справжня ж причина збільшення навантаження для мене залишилося загадкою, і якщо хтось розбирається в суті питання — діліться міркуваннями в коментарях.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.