当前位置: 首页 > 知识库问答 >
问题:

如何在 Swift 协议中定义可选方法?

薛宇
2023-03-14

在 Swift 中可能吗?如果没有,那么是否有解决方法可以做到这一点?

共有3个答案

邹修真
2023-03-14

这是委托模式的一个具体示例。

设置您的协议:

@objc protocol MyProtocol:class
{
    func requiredMethod()
    optional func optionalMethod()
}

class MyClass: NSObject
{
    weak var delegate:MyProtocol?

    func callDelegate()
    {
        delegate?.requiredMethod()
        delegate?.optionalMethod?()
    }
}

将委托设置为类并实现协议。请参阅不需要实现可选方法。

class AnotherClass: NSObject, MyProtocol
{
    init()
    {
        super.init()

        let myInstance = MyClass()
        myInstance.delegate = self
    }

    func requiredMethod()
    {
    }
}

一件重要的事情是,可选方法是可选的,在调用时需要一个“?”。提到第二个问号。

delegate?.optionalMethod?()
陶超
2023-03-14

在Swift 2及以后的版本中,可以添加协议的默认实现。这为协议中的可选方法创造了一种新的方式。

protocol MyProtocol {
    func doSomethingNonOptionalMethod()
    func doSomethingOptionalMethod()
}

extension MyProtocol {
    func doSomethingOptionalMethod(){ 
        // leaving this empty 
    }
}

这并不是创建可选协议方法的好方法,但可以在协议回调中使用结构。

我在这里写了一个小总结:https://www.avanderlee.com/swift-2-0/optional-protocol-methods/

蒋典
2023-03-14
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类符合它。此外,这意味着您可以利用强大的泛型系统。

    当遇到符合此类协议的类型时,您可以始终确保满足所有要求。它总是具体实现或默认实现。这就是“接口”或“契约”在其他语言中的行为方式。

    缺点

    >

  • 对于非无效要求,您需要有一个合理的默认值,这并不总是可能的。然而,当您遇到这个问题时,这意味着要么这样的需求真的没有默认实现,要么您在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 */
            }
        }
    }
    

    没有办法实现这样的优化-您无法知道您的委托是否实现了方法。

    虽然有许多不同的方法可以解决这个问题(使用可选的闭包,不同的委托对象用于不同的操作等等),但是这个例子清楚地说明了这个问题。

    @objc protocol MyProtocol {
        @objc optional func doSomething()
    }
    
    class MyClass: NSObject, MyProtocol {
        /* no compile error */
    }
    

    优势

    • 不需要默认实现。您只需声明一个可选方法或变量,即可开始使用。

    缺点

    >

  • 它要求所有一致类型都与Objective-C兼容,从而严重限制了协议的功能。这意味着,只有继承自<code>NSObject</code>的类才能符合此类协议。没有结构,没有枚举,没有关联的类型。

    您必须始终通过可选调用或检查一致性类型是否实现可选方法来检查可选方法是否实现。如果您经常调用可选方法,这可能会引入很多样板文件。

  •  类似资料:
    • 问题内容: 在Swift中有可能吗?如果没有,那么是否有解决方法? 问题答案: 1.使用默认实现(首选)。 优点 不涉及Objective-C运行时 (至少没有明确 涉及 )。这意味着您可以使其符合结构,枚举和非类。同样,这意味着您可以利用强大的泛型系统。 *当遇到符合此类协议的类型时, *您始终可以确保满足所有要求 。它始终是具体实现或默认实现。这就是“接口”或“合同”在其他语言中的行为方式。

    • 问题内容: 我有以下类层次结构: 实现一种协议方法,例如 在继承自的类中,不再调用新的可选协议方法,例如 问题答案: tl; dr,您需要在函数声明之前添加其Objective-C声明,例如 借助《Swift 3迁移指南》,我被告知这是一个解决方案,其中指出: 如果在声明符合性的类的子类中实现可选的Objective-C协议要求,则会看到警告,“实例方法’…’几乎与协议’…’的可选要求’…’相匹配

    • 问题内容: Swift 4通过该协议引入了对本机JSON编码和解码的支持。如何为此使用自定义键? 例如,说我有一个结构 我可以将其编码为JSON。 我可以将此编码回一个对象。 但是如果我有一个json对象 我怎么会告诉解码器上是映射到?我相信您使用的是新协议,但是我不知道该如何使用。 问题答案: 手动自定义编码键 在您的示例中,由于所有属性也都符合,因此您将获得自动生成的符合。这种一致性会自动创建

    • 问题内容: 如何设置协议的可选属性?例如,UITextInputTraits具有许多可选的读/写属性。当我尝试以下操作时,出现编译错误(无法在“ textInputTraits”中分配给“ keyboardType”): 通常,在访问协议的可选属性时,您会添加问号,但这在分配值时不起作用(错误:无法分配给该表达式的结果): 该协议如下所示: 问题答案: 在Swift中是不可能的(还好吗?)。从AD

    • 元数据3.proto my_proto_file.proto 生成元数据3\u pb2。py并在protoc插件中使用它,如下所示, my\u proto\u file\u pb2。py公司 访问文件中定义的选项与生成代码中设置的选项相同 但从外部proto文件导入的选项似乎未设置,因此无法访问

    • 问题内容: 我想使用一种接受通用输入并返回通用值的方法来创建协议。 到目前为止,这是我尝试过的方法,但是会产生语法错误。 使用未声明的标识符T。 我究竟做错了什么? 问题答案: 协议略有不同。查看Apple文档中的“关联类型” 。 这就是您在示例中使用它的方式