import UIKit final class ReusableCollectionViewDataSource: NSObject, UICollectionViewDataSource where V: ReusableCollectionViewCell { typealias ConfigureCell = (T, V) -> Void var models: [T] private let configureCell: ConfigureCell init(models: [T], cellConfigurator: @escaping ConfigureCell) { self.models = models self.configureCell = cellConfigurator } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return models.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell: V = collectionView.dequeue(for: indexPath) let model = models[indexPath.row] configureCell(model, cell) return cell } } class ReusableCollectionViewCell: UICollectionViewCell { var model: V? } /* private var dataSource: ReusableCollectionViewDataSource? self?.dataSource = ReusableCollectionViewDataSource(models: data) { model, cell in cell.model = model } self?.collectionView.dataSource = self?.dataSource