Swift Objective-C任择议定书方法的默认实现
如何为Objective-C可选协议方法提供默认实现 前Swift Objective-C任择议定书方法的默认实现,swift,protocols,Swift,Protocols,如何为Objective-C可选协议方法提供默认实现 前 期望值:任何符合AVSpeechSynthezerDelegate的类都应该在演讲结束时运行上述函数。您完全按照实现它的方式来执行。不同之处在于方法的实际调用方式 让我们举一个非常简单的例子: @objc protocol FooProtocol { optional func bar() -> Int } class Omitted: NSObject, FooProtocol {} class Implemented:
期望值:任何符合AVSpeechSynthezerDelegate的类都应该在演讲结束时运行上述函数。您完全按照实现它的方式来执行。不同之处在于方法的实际调用方式 让我们举一个非常简单的例子:
@objc protocol FooProtocol {
optional func bar() -> Int
}
class Omitted: NSObject, FooProtocol {}
class Implemented: NSObject, FooProtocol {
func bar() -> Int {
print("did custom bar")
return 1
}
}
通过不添加其他代码,我希望必须使用以下代码:
let o: FooProtocol = Omitted()
let oN = o.bar?()
let i: FooProtocol = Implemented()
let iN = i.bar?()
其中上的和
中的最后都有类型Int?
,
上的是nil
,
中的是1
,我们看到文本“did custom bar”
打印出来
重要的是,不是可选的链接方法调用:bar?()
,即括号中方法名称之间的问号。这就是我们必须从Swift调用可选协议方法的方式
现在,让我们为协议添加一个扩展:
extension FooProtocol {
func bar() -> Int {
print("did bar")
return 0
}
}
如果我们坚持我们的原始代码,在那里我们可以选择链接方法调用,那么行为没有变化:
然而,随着协议的扩展,我们不再需要有选择地展开。我们可以将可选的展开取出,扩展名为:
不幸的是,这并不一定特别有用,不是吗?现在我们每次只调用扩展中实现的方法
因此,如果您使用协议和调用方法来控制类,那么有一个稍微好一点的选项。您可以检查类是否响应选择器:
let i: FooProtocol = Implemented()
if i.respondsToSelector("bar") {
i.bar?()
}
else {
i.bar()
}
这也意味着您必须修改协议声明:
@objc protocol FooProtocol: NSObjectProtocol
添加NSObjectProtocol
允许我们调用respondsToSelector
,并且根本不会改变我们的协议。为了实现标记为@objc
的协议,我们必须从NSObject
继承
当然,尽管如此,任何Objective-C代码都无法在您的Swift类型上执行此逻辑,并且可能无法实际调用这些协议扩展中实现的方法。因此,如果你试图从苹果的框架中获得一些东西来调用扩展方法,那么你似乎运气不好。而且,即使您试图在Swift中调用其中一个,如果它是协议方法标记为可选
,似乎也没有很好的解决方案。谢谢您的详细解释!因此,如果我们不能像苹果的框架一样控制协议
,我们似乎无法为它们提供默认实现。你可以。您不能在@objc
协议中提供可选方法的默认实现,任何不知道扩展的代码都会调用这些方法。必须知道扩展名,因为只有Swift才能编写正确的代码来调用这两个扩展名(据我所知),如果Swift不知道扩展名,则无法编译调用这两个扩展名的正确代码。是的。我指的是可选方法。谢谢
@objc protocol FooProtocol: NSObjectProtocol