Может ли UITableViewDiffableDataSource обнаружить измененный элемент? - PullRequest
0 голосов
/ 07 апреля 2020

(Вопрос был переписан после обсуждения с @AndreasOetjen ниже. Спасибо за его комментарии.)

Я столкнулся с проблемой при использовании UITableView с расширяемым источником данных. В моем приложении, когда пользователь изменяет элемент, он может изменить другой элемент, который отображается в том же табличном представлении. Проблема в том, что после того, как я создал и применил новый моментальный снимок, содержащий новые значения обоих элементов, пользовательский интерфейс косвенно измененного элемента не был обновлен.

Сначала я подумал, что источник данных, способный к диффузии, может обнаружить значение элемента изменить в другом снимке. Например, это может работать следующим образом: если он обнаружил, что оба снимка содержат один и тот же элемент (то есть элементы в обоих снимках имеют одинаковое значение ha sh), он сравнил их значения и обновил строку этого элемента в табличном представлении, если значение изменилось , Однако позже я понял, что, возможно, это не сработало, потому что в источнике данных, который можно распространить, не определено никакого API для получения и сравнения значения элемента (моя первоначальная мысль заключалась в том, что он использовал description вычисляемое свойство и == операцию, но теперь я верю, что это не так).

Так что мое текущее понимание - это источник данных, который использует ха sh элемента для обнаружения изменения порядка элементов (т. е. новый элемент вставлен, старый элемент все еще существует, et c.), вместо изменение значения элемента (т. е. старый элемент все еще существовал, но его значение изменилось). Если это понимание верно, то возникает вопрос: как использовать источник данных с возможностью преобразования для реализации следующего сценария?

  • Элемент имеет несколько свойств. Одно свойство (назовем его свойством A) отображается в пользовательском интерфейсе, но не используется для генерации ha sh.
  • Элемент существует как в старых, так и в новых снимках, но его свойство A изменяется. Поэтому его пользовательский интерфейс необходимо обновить.

В старом UITableView API это можно реализовать, вызвав reloadRows() или reloadData(). Но как это сделать, используя диффузный источник данных?

ОБНОВЛЕНИЕ :

Потратив время на эксперименты и решение проблемы, я полагаю, что понимание в приведенном выше вопросе было неверным. Пожалуйста, смотрите мой ответ ниже. Я считаю, что это объясняет, как работает источник данных. Я надеюсь, что это поможет другим, у кого будет такая же путаница. Я был бы рад оказаться неправым. В самом деле. Поэтому, пожалуйста, оставьте свой ответ, если вы думаете по-другому.

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

После почти однодневных бессмысленных экспериментов, я полагаю, что я выяснил, как работает работоспособный источник данных, и решил эту проблему, основываясь на этом понимании (оказалось, что моя первоначальная мысль была почти правильной).

Используемый источник данных использует предмет ha sh для идентификации предмета. Для одного и того же элемента, который существует как в старых, так и в новых моментальных снимках, диффузный источник данных проверяет, изменяется ли элемент, выполняя операцию "==" со своими старыми и новыми значениями.

После расчета выходит, это выглядит довольно очевидным и простым подходом. Но это настолько фундаментально, что я не могу понять, почему это нигде явно не упоминается.

Итак, чтобы ответить на мой первоначальный вопрос, да, источник данных, способный к изменению, может обнаружить изменение значения элемента. Тем не менее, становится сложно, когда значение элемента имеет ссылочный тип, и / или текст, показанный в строке, является, скажем, свойствами объектов, на которые ссылается этот объект (например, отношение в Базовых данных), и т. Д. c.

Еще одна заметка. Использование всей структуры элемента или только его части для создания элемента ha sh не имеет значения, если только он идентифицирует элемент. Я предпочитаю использовать только ту часть предмета, которая действительно его идентифицирует.

1 голос
/ 07 апреля 2020

Я немного озадачен вашим последним предложением: вы пишете мой элемент - это перечисление со связанными значениями ссылочного типа , но в приведенном выше примере вы используете struct Book, который является типом значения , Независимо от этого, в любом случае необходимо помнить следующее:

Хеширование - это все о «объектной» идентичности. Это просто своего рода ярлык для улучшения сравнения идентификаторов, сворачивание и т. Д. c.

Если вы предоставляете собственную реализацию ha sh, два объекта a и b должны вести себя так, чтобы a == b подразумевает, что также hash(a) == hash(b) (обратное почти всегда также верно, но возможны столкновения - особенно со слабыми алгоритмами ha sh - когда это не так).

Так если у вас есть только sh title и author, то вы должны реализовать оператор сравнения таким образом, чтобы он также сравнивал только title и author. Затем, если notes изменится, ни источник данных, ни какое-либо тело не будут обнаруживать изменения идентичности вообще.

UITableViewDiffableDataSource - это средство, облегчающее синхронизацию операторов вставки / удаления между представлением и источником данных. Если вы когда-либо получали это

*** Завершение приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: «Неверное обновление: недопустимое количество разделов. Количество разделов, содержащихся в табличном представлении после обновления (3), должно быть равно количеству разделов, содержащихся в табличном представлении до обновления (3), плюс или минус количество вставленных или удаленных разделов (0 вставлено, 2 удалено). '

тогда ваш источник данных - это ваш друг.

Надеюсь, это немного поможет.

...