The title's a mouthful, so let me elaborate.
Suppose you have the following set up:
import Foundation
import Foundation
@objc protocol ObjCProtocol {
@objc optional func optionalFunc1()
@objc optional func optionalFunc2()
}
class SuperClass<T>: ObjCProtocol {
func optionalFunc1() {
print("SuperClass.optionalFunc1()")
}
}
class SubClass: SuperClass<Void> {
func optionalFunc2() {
print("SuperClass.optionalFunc2()")
}
}
let s1: ObjCProtocol = SuperClass<Void>()
s1.optionalFunc1!()
let s2: ObjCProtocol = SubClass()
s2.optionalFunc1!()
s2.optionalFunc2!()
optionalFunc2
looks like it's an implementation of the optional func optionalFunc2()
requirement of ObjCProtocol
. However, when you try it, it explodes:
SuperClass.optionalFunc1()
SuperClass.optionalFunc1()
objc[68263]: -[main.SubClass optionalFunc2]: unrecognized selector sent to instance 0x7ff13fc05410 (no message forward handler is installed)
Interestingly, all this works if you make SuperClass
non-generic:
import Foundation
@objc protocol ObjCProtocol {
@objc optional func optionalFunc1()
@objc optional func optionalFunc2()
}
class SuperClass: ObjCProtocol {
func optionalFunc1() {
print("SuperClass.optionalFunc1()")
}
}
class SubClass: SuperClass {
func optionalFunc2() {
print("SuperClass.optionalFunc2()")
}
}
// and from here... it works.
let s1: ObjCProtocol = SuperClass()
s1.optionalFunc1!()
let s2: ObjCProtocol = SubClass()
s2.optionalFunc1!()
s2.optionalFunc2!()
Background
Here's the background of how I stumbled into this issue, in case anyone's interested. Above is a minimal replication of my issue, which actually has to do with NSOutlineViewDelegate
. I have Swift class declared like so:
class OutlineViewDelegate<Model: NSObject>: NSObject, NSOutlineViewDelegate
It has an array of OutlineViewColumnConfiguration<Model>
member. Each OutlineViewColumnConfiguration
contains a render
function, which takes a NSTableCellView
and Model
. This implementation of delegate uses these closures to prepare the cells, rather than using a massive switch statement in outlineView(_:viewFor:item:)
.
I then have a subclass of that class, which wants to implement some less-abstract behavior of NSOutlineViewDelegate
(e.g. responding to selections).