在 Swift 中有可能吗?如果没有,那么是否有解决方法?
最佳答案
1。使用默认实现(首选)。
protocol MyProtocol {
func doSomething()
}
extension MyProtocol {
func doSomething() {
/* return a default value or just leave empty */
}
}
struct MyStruct: MyProtocol {
/* no compile error */
}
优势
不涉及 Objective-C 运行时(嗯,至少不明确)。这意味着您可以使结构、枚举和非
NSObject
类符合它。此外,这意味着您可以利用强大的泛型系统。遇到符合此类协议(protocol)的类型时,您始终可以确保满足所有要求。它始终是具体实现或默认实现。这就是“接口(interface)”或“契约”在其他语言中的行为方式。
缺点
对于非
Void
需求,您需要有一个合理的默认值,这并不总是可能的。但是,当你遇到这个问题时,要么是这个需求真的没有默认实现,要么是你的API设计有误。您无法区分默认实现和根本没有实现,至少在没有解决具有特殊返回值的问题时是这样。考虑以下示例:
protocol SomeParserDelegate { func validate(value: Any) -> Bool }
如果您提供一个只返回
true
的默认实现 — 乍一看没问题。现在,考虑以下伪代码:final class SomeParser { func parse(data: Data) -> [Any] { if /* delegate.validate(value:) is not implemented */ { /* parse very fast without validating */ } else { /* parse and validate every value */ } } }
没有办法实现这样的优化——您无法知道您的委托(delegate)是否实现了某个方法。
虽然有许多不同的方法可以解决这个问题(使用可选的闭包、不同的委托(delegate)对象用于不同的操作等等),但这个例子清楚地说明了这个问题。
2。使用 @objc 可选
。
@objc protocol MyProtocol {
@objc optional func doSomething()
}
class MyClass: NSObject, MyProtocol {
/* no compile error */
}
优势
- 不需要默认实现。您只需声明一个可选方法或变量,然后就可以开始了。
缺点
它要求所有符合的类型都与 Objective-C 兼容,从而严重限制了协议(protocol)的功能。这意味着,只有继承自
NSObject
的类才能符合此类协议(protocol)。没有结构、没有枚举、没有关联类型。您必须始终检查是否实现了可选方法,方法是可选地调用或检查符合类型是否实现它。如果您经常调用可选方法,这可能会引入很多样板文件。
关于ios - 如何在 Swift 协议(protocol)中定义可选方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24032754/