Swift protocol extension with method in wrong delegate still works(?!)

Viewed 73

I have a class that is using UITableView, for example:

class tableViewController {

    tableView.dataSource = self
    tableView.delegate = self

I noticed that one of the functions is in the wrong protocol extension:

extension tableViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {

But it should be in ->

extension tableViewController: UITableViewDelegate {

This is in some code that I've had for quite sometime (even in a released app, but it has never misbehaved or produced errors.

Is this expected behavior due to some underlying mechanism.

2 Answers

Extension is not Inheritance that follow hierarchy, there is no hierarchy in extension. It means that if confirm to a protocol in any extension of your class, the functions of that protocol will be accessible within other extension.

It doesn't matter which extension the delegate methods are declared in, as long as the methods are visible from the extension that declares the conformance to the protocol.

To find witnesses in tableViewController for the methods in UITableViewDelegate, the compiler looks at all the methods that tableViewController has. Well, methods in any visible extension of tableViewController is a "method that tableViewController has", right? So naturally, the compiler would consider both extensions.

I can even declare the methods in a separate extension:

extension tableViewController: UITableViewDataSource { /* empty */ }
extension tableViewController: UITableViewDelegate { /* empty */ }
extension tableViewController {
    // all the data source and delegate methods go here
}

That works too, because the methods from the third extension are visible from the first two extensions.

Whether putting data source methods in the delegate extension is good practice, however, is a different story. I would say that this is quite confusing. Even if the compiler allows it, you should not do it unless you have a very good reason.

Related