Why I can't use @objc dynamic in the protocol extension?

Hi I tried to write a protocol that inherits the objc protocol, and override some of the behavior of the original objc protocol, like:

@objc protocol NSTableViewSectionSupportProtocol: NSTableViewDataSource { }
extension NSTableViewSectionSupportProtocol {
	// MARK: - row related
	func numberOfRows(in tableView: NSTableView) -> Int { ... } 
}

But the compiler give me this error:

Non-'@objc' method 'numberOfRows(in:)' does not satisfy optional requirement of '@objc' protocol 'NSTableViewDataSource'

But if I add @objc, compiler will give me this error:

@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes

Then I tried @objc dynamic, it didn't help.

I can think of the reason why I can't use @objc in a protocol extension is because of static dispatching, but protocol extension did support dynamic function, so why can't I use @objc dynamic?

Looking for an answer, thanks!

You’ve pretty much gotten it: extending a protocol with an @objc member would have to modify existing classes that conform to that protocol to provide this member (because in Objective-C, everything is dynamic dispatch by default through the method table on the class only).

Now, theoretically the compiler could allow this in your case, because you’re extending the protocol in the same module where it’s defined. So you know that every class that can see the protocol to conform to it can also see the extension, and copy the method into the class. But that would have to go through the Swift Evolution process. (It also wouldn’t work in library evolution mode, because that mode allows your library to be swapped out without rebuilding clients.)

Sorry for the inconvenience. You can sometimes get the same effect with that good old OOP standby: a base class.

6 Likes

Got it. Thanks for your reply!