Overload resolution: extension vs. subclass


(Jon Shier) #1

Given:

In App module:

extension UINavigationController {
    @objc func popToViewControllerType(_ viewControllerType: UIViewController.Type, animated: Bool) -> [UIViewController]? { ... }
}

In test module:

class TestNavigationController: UINavigationController {
    func popToViewControllerType(_ viewControllerType: UIViewController.Type, animated: Bool) -> [UIViewController]? { ... }
}

When called in a test, the extension implementation is always called. When both definitions are marked @objc, the compiler produces a duplicate definition error. When neither has @objc, it compiles, but produces the same behavior, where the extension is always called.

Is this a Swift or Obj-C behavior? Any way to override the extension implementation from a subclass?


(Jordan Rose) #2

I believe you can mark the extension method dynamic and write @objc dynamic override in the test module, to make it clear that you're using ObjC selectors and all the collisions that entails. In general, though, no: methods in extensions in Swift are stuck being final today.

(See also [Pitch] Overridable Members in Extensions, which did not get traction at the time but which we'll probably add someday.)


(Jon Shier) #3

Adding dynamic doesn't seem to have made a difference for the compiler or runtime behavior.