Reputation: 11113
I have a Swift class called Helpers
defined as follows:
class Helpers : NSObject {
class func sayValue(value:Printable) {
println(value)
}
}
I am trying to use this in an Objective-C .m
file, like so:
[Helpers sayValue:@"Hello"];
But the compiler is complaining with the error: No known class method for selector 'sayValue:'
However if I change the sayValue
to have a strict type, it works fine:
class Helpers : NSObject {
class func sayValue(value:String) {
println(value)
}
}
What's going on here?
Upvotes: 0
Views: 861
Reputation: 535315
You've already figured it out. Swift protocols don't map as types into Objective-C.
Always just ask yourself "Could I say this in Objective-C?" You can't say this in Objective-C:
+ (void) sayValue: (Printable*) value { ... }
That's illegal, because Printable (a protocol) isn't a type. So your Swift function defined that way doesn't magically map upward into Objective-C, as it has nothing to map to. It is filtered out, and Objective-C never sees it.
What I'm finding is that all this works remarkably cleanly. I was afraid that a Swift class that uses any non-Objective-C features wouldn't map to an Objective-C class at all. But, on the contrary, you can use all the pure-Swift features you like, and they simply don't map up into Objective-C: they are cleanly filtered out, and those parts of your Swift class that do map into Objective-C work just fine from Objective-C. It's quite brilliant.
You are free to define a protocol that maps as a type for purposes of, say, defining a delegate. But to do that, you must expose the protocol using @objc
. For example, from one of my apps:
@objc protocol ColorPickerDelegate {
func colorPicker (/*...*/)
}
class ColorPickerController : UIViewController {
weak var delegate: ColorPickerDelegate?
// ...
}
You can't talk that way unless the protocol is @objc
. Now Objective-C understands the type of delegate
to mean id<ColorPickerDelegate>
and you're in business.
(So you could probably talk the way you're suggesting by defining an @objc
protocol MyPrintable which does nothing but adopt Printable; I haven't tried it, however, so that's just a conjecture.)
Upvotes: 4