在 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/52191378/