在Objective-C中使用具有协议类型参数的Swift函数

时间:2014-06-20 17:08:58

标签: swift

我有一个名为Helpers的Swift类定义如下:

class Helpers : NSObject {
    class func sayValue(value:Printable) {
        println(value)
    }
}

我试图在Objective-C .m文件中使用它,如下所示:

[Helpers sayValue:@"Hello"];

但编译器抱怨错误:No known class method for selector 'sayValue:'

但是,如果我将sayValue更改为严格类型,则可以正常工作:

class Helpers : NSObject {
    class func sayValue(value:String) {
        println(value)
    }
}

这里发生了什么?

1 个答案:

答案 0 :(得分:4)

你已经明白了。 Swift协议不会将类型映射到Objective-C。

总是问自己"我可以在Objective-C中说这个吗?"你不能在Objective-C中这样说:

+ (void) sayValue: (Printable*) value { ... }

这是非法的,因为Printable(协议)不是一种类型。所以你定义的Swift函数并没有神奇地向上映射到Objective-C,因为它没有任何映射。它被过滤掉了,而Objective-C从未见过它。

我发现所有这些都非常干净。我担心使用任何非Objective-C功能的Swift类不会映射到Objective-C类所有。但是,恰恰相反,你可以使用你喜欢的所有纯Swift功能,而且它们只是没有映射到Objective-C:它们被彻底过滤掉了,你的Swift类的那些部分从Objective-C开始映射到Objective-C工作。它非常棒。


您可以自由定义一个映射为类型的协议,例如,定义委托。但要做到这一点,您必须使用@objc公开协议。例如,来自我的一个应用程序:

@objc protocol ColorPickerDelegate {
    func colorPicker (/*...*/)
}

class ColorPickerController : UIViewController {
    weak var delegate: ColorPickerDelegate?
    // ...
}

除非协议是@objc,否则你不能这样说。现在,Objective-C了解delegate的类型id<ColorPickerDelegate>,并且您已经开始营业。

(所以你可以通过定义一个@objc协议MyPrintable来说明你所建议的方式MyPrintable除了采用Printable之外什么都不做;但我还没有尝试过,所以&#39;只是一个猜想。)