当前位置: 首页 > 面试题库 >

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

能翔宇
2023-03-14
问题内容

在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使其符合结构,枚举和非类。同样,这意味着您可以利用强大的泛型系统。

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

缺点

  • 对于非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 */
        }
    }
}

无法实现这种优化-您不知道委托是否实现了一种方法。

尽管有多种方法可以解决此问题(使用可选的闭包,针对不同的操作使用不同的委托对象,仅举几例),但该示例清楚地提出了问题。

2.使用@objc optional

@objc protocol MyProtocol {
    @objc optional func doSomething()
}

class MyClass: NSObject, MyProtocol {
    /* no compile error */
}

优点

  • 无需默认实现。 您只需声明一个可选方法或变量,就可以使用了。

缺点

  • 要求所有符合类型都必须与Objective-C兼容 ,从而严重限制了协议的功能 。这意味着,仅继承自NSObject该类的类可以遵循此类协议。没有结构,没有枚举,没有关联的类型。

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



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

  • 问题内容: 我有以下类层次结构: 实现一种协议方法,例如 在继承自的类中,不再调用新的可选协议方法,例如 问题答案: 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文档中的“关联类型” 。 这就是您在示例中使用它的方式