ios - 如何在 Swift 协议(protocol)中定义可选方法?

标签 ios swift optional-parameters swift-protocols swift-extensions

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

相关文章:

ios - 如何使用 segue 进行导航?

iphone - 将第三方库添加到 iPhone 应用程序时如何设置 'Header Search path' 的路径

iOS 位置推送服务扩展。 CLLocationPushServiceErrorDomain代码: 1

swift - 如何使用 Swift 2 在 OS X 上删除系统域文件?

ios - 如何将新添加的 UIWindow 保持在顶部

c++ - 函数中输出容器默认值的开始

dictionary - 带有选项参数或使用空字典作为默认参数的函数

ios - UIModalPresentationPopover 的箭头不指向 UICollectionViewCell

swift - 图像无法在表格 View 中显示

c# - 通过反射调用带有可选参数的方法