我似乎可以在Swift API中使用,因此需要深入到Objective-C来实现它 . 我在https://gist.github.com/BennettSmith/1613121使用例程打印出每个类及其父类的所有方法,并且选择器总是显示为"init",但根据我的理解,它应该显示为"init:",因为它有一个参数 .
JSONJoy协议是:
public protocol JSONJoy {
init(_ decoder: JSONDecoder)
}
为了测试,我尝试创建自己的名为“TestProtocol”的协议 . 以下是我的结果 .
init(str: String) {}
显示"initWithStr:"的选择器
required public init(str: String) {}
仍显示 "initWithStr:" 的选择器
取消协议并使用方法签名 "init(str: String)" 直接在我的类中实现方法,它仍然显示为 "initWithStr:".
使用和不使用“TestProtocol”的所有上述测试都按预期生成选择器 .
但是,无论我如何操作JSONJoy协议签名,当我列出类的选择器时,它总是显示为没有任何参数的普通 "init" . 我尝试删除"_"并在协议中添加其他参数,但它仍然是"init"
2 回答
要在Objective-C中提供Swift协议,您需要将
@objc
属性添加到协议声明中 .您可以使用
respondsToSelector()
测试Objective-C方法签名,如以下Playground示例所示:具有第一个参数且外部参数名称为
foo
(即init(foo bar:Int)
)的初始值设定项在Objective-C中默认为initWithFoo:
. 如果未明确指定初始化程序参数的外部名称,则将隐式使外部名称与内部名称相同 . 因此,当您编写init(str: String)
时,它隐式init(str str: String)
,您必须像MyClass(str: something)
一样使用它,而Objective-C选择器是initWithStr:
.您始终可以使用
_
显式禁止外部名称,您可以在其中指定外部名称 . 这是他们在JSONJoy
(init(_ decoder: JSONDecoder)
)中对初始化程序的第一个参数所做的 . 你可以做同样的事情:然后你会像
MyClass(something)
一样使用它,而Objective-C选择器将是init: