Tableview Subclass implementing delegate datasource I have two view controllers which have same tableview. One is for Post and one is for Profile, which also contains a post by a user. I have decided to reuse the code, so I have created the class PostTableView.

class PostTableView: UITableView {

    var arrayPosts:[PostTableViewCompitible] = [] {
        didSet {
            self.reloadData()
        }
    }
    var btnCommentTapped:((ArrayInspireListCell) -&gt; ())?
    var heightOfRows = Dictionary&lt;IndexPath, CGFloat&gt;()
    var indexOfCellBeforeDragging = 0


    override func awakeFromNib() {
        super.awakeFromNib()
        setupTableView()
    }

    private func setupTableView() {
        self.register(UINib.init(nibName: StoryBoard.Cells.ArrayInspireListCell, bundle: nil), forCellReuseIdentifier: StoryBoard.Cells.ArrayInspireListCell)
        self.dataSource = self
        self.delegate = self
        self.estimatedRowHeight = 470
        //    self.tableView.decelerationRate = UIScrollViewDecelerationRateFast
        self.rowHeight = UITableViewAutomaticDimension
        self.separatorStyle = .none


    }

}


With Delegate / Data source:

extension PostTableView:UITableViewDataSource,UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
        return self.arrayPosts.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
        let post = self.arrayPosts[indexPath.row]
        let cell = post.cellForTableView(tableview: tableView, atIndexPath: indexPath)
        cell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.row)
        cell.layer.shouldRasterize = true
        cell.layer.rasterizationScale = UIScreen.main.scale

        cell.btnCommentTapped = self.btnCommentTapped

        cell.layoutIfNeeded()

        return cell
    }

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -&gt; CGFloat {
        if let height = self.heightOfRows[indexPath] {
            return height
        }
        return 470
    }

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        let height = cell.frame.size.height
        self.heightOfRows[indexPath] = height + 30
    }


}


Is it good practice to do so?
Personally I don't like the way UITableViews work with a delegate and dataSource yet there's no real way to say "Here's the data". You are kind of forced to either send around copies of your data or put everything into one class. There's tons of mixing of the M, V and C layers in one class going on.

However, it should be possible to use a separate implementation of the dataSource and `delegate. While in this example there's little code, in some cases you might cross (my personal) soft limit of 200 lines of code or even the hard limit of 300 in one file.

In my Objective-C / Storyboards days I actually had implementations where I would use several objects all linked together via @IBOutlets. So a delegate, dataSource and tableView. The delegate could have a weak ref to the dataSource and the dataSource had the actual data. Not using the selected mechanism for button-like actions could allow you to sever the ties between the delegate and the data.

So I don't disapprove of what you're doing because you're trying to do your best with the bad hand of cards that Apple dealt you. But you could try to have the data only exist on the dataSource implementation. Also I see you doing a lot of stuff to the cell in dequeue, that should definitely move to the implementation of the cell because it's doing V code in an M class. I use a configure(with: *someData*) function that sets it up further.

If you try to separate the M from the V and the C you will see pretty clearly where you should cut it up.