Выбор ответа Middle SwiftUI обновлено

Идентификаторы в ForEach

Вопрос

Почему ForEach(items.indices, id: \.self) опасен для списка, где элементы удаляются и переставляются?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Идентичность привязана к позиции: состояние переедет на чужие элементы. ForEach сопоставляет элементы между обновлениями по id.

Варианты ответа

  1. Индексы нельзя использовать в id: вообще, компилятор выдаст предупреждение
  2. Идентичность привязана к позиции: состояние переедет на чужие элементыправильный ответ
  3. Это медленнее примерно в 10 раз из-за хеширования Int на каждом обновлении
  4. SwiftUI запрещает indices в ForEach и падает при первом удалении

Разбор

ForEach сопоставляет элементы между обновлениями по id. Если id это индекс, то после удаления первого элемента элемент «1» становится элементом «0» с точки зрения SwiftUI: анимации и @State строк окажутся не на тех данных, а замыкания со старым индексом могут обратиться за пределы массива. Нужен стабильный идентификатор из данных (Identifiable). Для неизменяемых списков индексы допустимы, скорость тут ни при чём.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.