Уникальный идентификатор UITableViewCell?

#uitableview #xamarin.ios #deque

#uitableview #xamarin.ios #deque

Вопрос:

Я ищу способ однозначно идентифицировать экземпляры UITableViewCells даже после того, как они были переработаны (удалены из очереди) через dequeueReusableCell(строковый идентификатор) — без подклассов или использования объекта контейнера.

Итак, по сути, когда я создаю новую ячейку, я хочу использовать уникальный идентификатор этой ячейки в качестве ключа для хранения другого связанного объекта в словаре. Позже, когда ячейка будет переработана / удалена из очереди, я хочу прочитать соответствующий объект из словаря. Я полностью осознаю, что переработанная ячейка может быть помещена в любой индексный путь в таблице и может (скорее всего) содержать другие данные, чем раньше — другой объект действительно связан с экземпляром ячейки, а не с индексным путем.

Следует избегать потери связи с объектом. Полученный идентификатор должен любой ценой совпадать с тем, который использовался при создании ячейки.

Ранее это достигалось путем генерации случайного числа и сохранения его в качестве тега ячейки. Однако эти теги могут сталкиваться (когда одно и то же случайное число генерируется дважды), и я бы хотел реализовать предотвращение столкновений только в крайнем случае. Итак, я ищу лучший способ.

Я просмотрел свойства ClassHandle, Handle и SuperHandle. Похоже, что единственным, который остается неизменным среди dequeues, является ClassHandle .

Безопасно ли использовать свойство ClassHandle для этой цели? Если нет, какие еще есть варианты?

Комментарии:

1. Из любопытства, есть ли особая причина, по которой вы не хотите создавать подкласс UITableViewCell? Это, скорее всего, сделало бы ваше приложение намного менее сложным, потому что тогда вы могли бы хранить ссылки любого типа, которые вы хотите, непосредственно в ячейке и не беспокоиться об этом. Мы создали очень простой унаследованный класс с тегом Object, который является очень гибким и работал для каждого сценария, с которым мы сталкивались до сих пор.

2. Обе версии приложения для Android и iOS в настоящее время используют словарь для хранения дополнительного объекта для каждой ячейки (при необходимости). Я просто хотел бы оставаться последовательным.

Ответ №1:

Вы можете создать свое собственное монотонно увеличивающееся число:

 static int monotonicNumber;
  

а затем установите для тега значение:

 cell.Tag = System.Threading.Interlocked.Increment (ref monotonicNumber);
  

Обратите внимание на эту среду.Количество тиков не гарантируется уникальным, вы можете получить одинаковые количества тиков, если вы извлекаете его в быстрой последовательности. Я знаю, потому что это случилось со мной.

Комментарии:

1. 1) Почему статический? Пожалуйста, объясните. 2) Было бы нормально просто номер? AFAIK, только поток пользовательского интерфейса будет выполнять код пользовательского интерфейса.

2. 1) Почему бы и нет? Это действительно зависит от вашего кода, вы также можете использовать поле экземпляра, если знаете, что вам не нужны уникальные идентификаторы для нескольких экземпляров класса. Поскольку я не знал, нужно ли вам это или нет, я выбрал безопасный вариант: статический. 2) Да, если он будет использоваться только потоком пользовательского интерфейса, вы можете использовать оператор увеличения .

Ответ №2:

В дополнение к ответу Джонатана Пеппера, это довольно распространенный метод, используемый в многочисленных примерах в Интернете:

Всякий раз, когда вы создаете новую ячейку в своем GetCell методе, задайте ячейку Tag с помощью

 cell.Tag = Environment.TickCount;
  

Это особенно полезно, если у вас есть пользовательский объект cell. Затем ваши ячейки можно отслеживать в вашем классе источника данных, например, с помощью словаря:

 Dictionary<int, your_cell_type> cells = ...
  

Если вам нужно отследить что-то конкретное для ячейки, вы можете использовать Tag для поиска этого в вашем объекте словаря.

Комментарии:

1. Выглядит многообещающе, я попробую и отчитаюсь.

2. Вот оригинальная статья, из которой я почерпнул эту идею: infoq.com/articles/monotouch-custom-tables

3. Если вы используете этот подход, вы должны быть очень осторожны, чтобы удалить ссылку на ячейку в объекте dictionary, чтобы у вас не было утечки памяти с кучей ячеек, накапливающихся в словаре.

Ответ №3:

Вы также можете использовать идентификатор Guid: http://msdn.microsoft.com/en-us/library/system.guid .newguid.aspx

Это стандартные, доказавшие, что они всегда уникальны, идентификаторы для .Net. Они доступны как в Windows, так и в Mono, запущенных в любом месте.

Я предполагаю, что свойство Tag является объектом, и вы можете сохранить его там (но может быть int, знающим Apple). Если нет, вы можете создать подкласс UITableViewCell, чтобы добавить свойство типа Guid.

Комментарии:

1. Тег — это целое число (к сожалению)

2. Похоже, вам следует подкласс UITableViewCell для ваших целей. Они все равно будут правильно отображаться с помощью DequeueReuseableCell, вы можете просто привести к своему новому типу.