With the transition from Swift 2 -> 3 I’ve started running into one particular issue VERY often (although it’s not necessarily specific to the transition). If a protocol method is optional (either because it is an @objc optional or because it has a default implementation) there is a risk that the conformer will have a misspelled or slightly incorrectly typed implementation of the method. For instance:
protocol RouteDestinationViewController: class { static func viewController(with url: URL, properties: [String:String]) -> UIViewController? } extension RouteDestinationViewController where Self: UIViewController { static func viewController(with url: URL, properties: [String:String]) -> UIViewController? { return Self.init() } } class FooController: UIViewController, RouteDestinationViewController { static func viewController(with url: URL, properties: [String:Any]) -> UIViewController? { return FooController(properties: properties) } } Notice the issue there? Properties is supposed to be [String:String], but FooController uses [String:Any] (this is an exact issue I ran into after a small refactor). When viewController(with:properties:) is called, it will use the default implementation instead of what the compiler sees as a completely different method. Over the betas the compiler has gotten better warnings about this, but is still not 100%. Other cases of this issue are common with imported ObjC protocols that have different naming in Swift. In some cases an @objc name must be applied to ensure it is declared in a way that the protocol can see it. We solve this problem with subclassing by requiring “override”. If the override keyword is present but the superclass doesn’t have a matching method, the compiler warns us about it. Similarly if the superclass implements the same method and the subclass doesn’t include override, we get a warning so that it is clear that you are overriding behavior. For protocols, I don’t think a required keyword would be the best approach. It’s a completely valid case that a type could conform to a protocol using existing methods, perhaps even from a different module. Further, a single method could satisfy multiple protocols, and be overriden from a superclass. What I would propose would be something like an optional override(<#protocol name#>). Something like the following: override(RouteDestinationViewController) static func viewController(with url: URL, properties: [String:Any]) -> UIViewController? { return FooController(properties: properties) } A method should be able to include multiple overrides (including a bare override to indicate that it is overriding a class method). Thoughts? Are you seeing similar issues? David Beck http://davidbeck.co http://twitter.com/davbeck http://facebook.com/davbeck
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution