---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.3
alternate:
  - https://divkit.tech/docs/en/concepts/reuse/ios.md
  - https://divkit.tech/docs/ru/concepts/reuse/ios.md
---
> **Documentation Index:** Fetch the complete configuration index at https://divkit.tech/docs/ru/llms.txt

# Переиспользование блоков на iOS

Переиспользование блоков в DivKit на iOS происходит при следующих событиях:
- [Установка новой DivData](#new-div-data).
- [Cкроллинг элементов в сложных контейнерах](#recycler-container): `gallery`, `grid`, `tabs`.

## Переиспользование при установке новой DivData {#new-div-data}

DivKit всегда пытается переиспользовать уже созданные элементы. Для этого используется метод `reuse` протокола `UIViewRenderable`, который определяет, может ли блок быть переиспользован.

### Диаграмма процесса переиспользования

Ниже представлена диаграмма процесса переиспользования блоков в iOS:

```mermaid
flowchart TD
    A[Запрос на переиспользование блока] --> B{Есть view для переиспользования?}
    B -->|Да| C{isBestViewForReuse?}
    B -->|Нет| G[Создать новый view]
    C -->|Да| D[Переиспользовать view]
    C -->|Нет| E{canConfigureBlockView?}
    E -->|Да| D
    E -->|Нет| G
    D --> F[Сконфигурировать view]
    G --> F
    F --> H[Вернуть view]
```

Процесс переиспользования включает следующие шаги:
1. Проверка наличия view для переиспользования
2. Проверка метода `isBestViewForReuse` для определения, является ли view лучшим кандидатом для переиспользования
3. Если view не является лучшим кандидатом, проверка метода `canConfigureBlockView`
4. Если view может быть переиспользован, обновление его конфигурации
5. Если view не может быть переиспользован, создание нового view
6. Конфигурация view и его возврат

### Особенности реализации методов переиспользования

В процессе переиспользования блоков в DivKit используются два ключевых метода: `canConfigureBlockView` и `isBestViewForReuse`:

1. **canConfigureBlockView** - базовый метод, который проверяет тип UIView. Его реализация обычно очень проста:

```swift
// Пример для ImageBlock
public func canConfigureBlockView(_ view: BlockView) -> Bool {
  view is RemoteImageViewContainer
}
```

2. **isBestViewForReuse** - для простых блоков (Image, Text) и некоторых составных блоков (Container, Gallery) по умолчанию просто вызывает `canConfigureBlockView`:

```swift
// Реализация по умолчанию в протоколе UIViewRenderable
public func isBestViewForReuse(_ view: BlockView) -> Bool {
  canConfigureBlockView(view)
}
```

3. **isBestViewForReuse для некоторых сложных блоков** - для определенных составных блоков (например, DecoratingBlock) имеет более сложную логику:

```swift
// Пример для DecoratingBlock
func isBestViewForReuse(_ view: BlockView) -> Bool {
  guard let view = view as? DecoratingView,
        view.childView != nil else { return false }
  return child.isBestViewForReuse(view.childView!)
}
```

В этом примере `isBestViewForReuse` не только проверяет тип view, но и:
- Требует наличия непустого дочернего view
- Рекурсивно проверяет, является ли дочерний view оптимальным для переиспользования

4. **Особенности составных блоков** - блоки, содержащие коллекции дочерних элементов (Container, Gallery), делегируют переиспользование дочерних элементов специальному методу `reused` для массивов:

```swift
// В ContainerBlockView
blockViews = blockViews.reused(
  with: model.children.map(\.content),
  attachTo: self,
  observer: observer,
  overscrollDelegate: overscrollDelegate,
  renderingDelegate: renderingDelegate
)
```

Метод `reused` сам реализует двухуровневую систему переиспользования для каждого дочернего элемента.

## Переиспользование в сложных контейнерах {#recycler-container}

В сложных контейнерах, таких как `gallery`, `grid` и `tabs`, DivKit использует механизм переиспользования ячеек коллекций UIKit. Каждый блок имеет свойство `reuseId`, которое используется для идентификации блоков, которые могут быть переиспользованы.

Например, в `GalleryView` метод `cellForItemAt` использует `block.reuseId` для получения переиспользуемой ячейки из коллекции:

```swift
let cell = collectionView.dequeueReusableCell(
  withReuseIdentifier: block.reuseId,
  for: indexPath
) as! CellType
```

По умолчанию `reuseId` возвращает строку "DefaultReuseId", но блоки могут переопределить это свойство для более точного контроля над переиспользованием.

### Использование свойства `reuse_id`

Для более эффективного переиспользования блоков в сложных контейнерах рекомендуется устанавливать свойство `reuse_id` для блоков с одинаковой структурой. Это позволит DivKit более эффективно переиспользовать представления.

{% cut "Пример:" %}

```json translate=no
{
    "type": "gallery",
    "items": [
        {
            "type": "container",
            "reuse_id": "video_block",
            "items": [
                {
                    "type": "video",
                    ...
                }
            ]
        },
        {
            "type": "container",
            "reuse_id": "image_block",
            "items": [
                {
                    "type": "image",
                    ...
                }
            ]
        },
        {
            "type": "container",
            "reuse_id": "image_block",
            "items": [
                {
                    "type": "image",
                    ...
                }
            ]
        },
        {
            "type": "container",
            "reuse_id": "video_block",
            "items": [
                {
                    "type": "video",
                    ...
                }
            ]
        }
    ]
}
```

{% endcut %}

В этом примере блоки с одинаковым `reuse_id` будут переиспользоваться между собой. Это особенно важно для тяжелых объектов, таких как `video`, чтобы избежать их ненужного пересоздания.

<!-- source: ru/_includes/index/troubleshooting.md -->
## Узнать больше {#troubleshooting}

Вы можете обсуждать интересующие вас темы в сообществе пользователей DivKit в Telegram: [https://t.me/divkit_community_ru](https://t.me/divkit_community_ru).



[Репозиторий DivKit](https://github.com/divkit/divkit)




<!-- endsource: ru/_includes/index/troubleshooting.md -->
