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

相关文章:

ios - 在具有动态单元高度的单元中添加 subview 的动画

ios - 如何根据 objective-c 中的TimeZone获取当前时间?

ios - NEHotspotConfigurationManager 收到此警报 :"Unable to join the network<name of network>"而错误为零

matlab:lsqcurvefit 和参数

iphone - 如何将NSMutableArray值转换为NSString?

ios - 在 String 中的特定字符串的字符串末尾添加一个字符串

windows - 你能在 Windows 上运行和编译 Swift 代码吗?

ios - Swift 中的 NSDictionary :Cannot subscript a value of type 'AnyObject?' with a index of type 'Int'

sql - 可选参数, "index seek"计划

python - 在任何 python API 文档中,为什么可选参数都以嵌套样式编写?