在Swift中实现ObjC协议

6
好的,这是一个大问题。我有一个用ObjC编写的库(这里),其中我们定义了一个协议。当我尝试在Swift文件中使用它时,我不断地遇到以下错误信息:

类型“XXX”不符合协议“XXX”

为了简化事情,我做了一个测试项目 - 它应该被创建为Swift项目。
然后创建一个ObjC头文件(我称之为StupidProtocol.h),里面包含以下协议(请注意每个名称和值都要与给定的完全匹配,包括大小写):
@protocol MyProtocol <NSObject>

- (NSString *)getAxisLabel:(id)axis Value:(CGFloat)value;

@end

在桥接头文件中:

#import "StupidProtocol.h"

然后回到Swift文件中:

class ViewController: UIViewController, MyProtocol
{
    func getAxisLabel(axis: AnyObject!, value: CGFloat) -> String! {
        return ""
    }
}

即使自动完成为我完成了getAxisLabel函数,我们仍然遇到了这个错误。我强烈怀疑问题在于参数"value"和它的函数参数"Value"。

非常感谢任何帮助。

编辑

请注意,这个库并不是我的技术产物,所以我无法更改它。我需要一种在Swift中使用它而不改变它原始声明的方式。我的例子只是为了简化我的问题。

我尝试过以下场景但没有成功:

“具有与协议要求的参数名称不同的参数名称”错误

func getAxisLabel(axis: AnyObject!, Value value: CGFloat) -> String! {
    return ""
}

“由于参数名称与协议所需的不同”错误
func getAxisLabel(axis: AnyObject!, Value: CGFloat) -> String! {
    return ""
}

'

'类型不符合协议'

'
func getAxisLabel(axis: AnyObject!, Value: CGFloat) -> NSString! {
    return ""
}

解决方案

请查看被采纳的答案


Obj-C是大写V,Swift是小写v。让它们都变成小写。在两者中都应该是小写的。 - Fogmeister
尝试使用外部参数名“Value”和内部参数名“value”编写Swift方法,例如:“Value value: CGFloat”。 - hola
那可能会解决问题,但你本来就不应该有大写字母V。去掉它就可以了。 - Fogmeister
请注意,这个方法声明不是我写的 - 我完全同意它被错误地声明了。但是我需要使用在Swift中有这个声明的库。如果你能以某种方式帮助我解决这个问题,那就太好了。 - hris.to
然后 @hola 修复 Value value: CGFloat 的问题应该可以解决。 - Fogmeister
1个回答

9

我不知道这是bug还是正常情况。这是Objective-C协议的方法。

- (NSString *)getAxisLabel:(id)axis Value:(CGFloat)value;

Value: 中大写的 "V" 在 Swift 中被映射为

func getAxisLabel(axis: AnyObject!, value: CGFloat) -> String!

(在value:中使用小写字母"v"),但没有任何一个

func getAxisLabel(axis: AnyObject!, value: CGFloat) -> String! { }
func getAxisLabel(axis: AnyObject!, Value: CGFloat) -> String! { }

被编译器接受以满足协议要求。

作为解决方法,您可以使用明确的Objective-C选择器名称来注释方法:

class ViewController: UIViewController, MyProtocol
{
    @objc(getAxisLabel:Value:)
    func getAxisLabel(axis: AnyObject!, value: CGFloat) -> String! {
        return ""
    }
}

1
你真是个救命恩人!我知道应该使用@objc关键字作为解决方法,但不知道如何确切地使用它。对于将来的参考来说,这很棒! - hris.to

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接