我怎样才能使协议实现成为函数的参数

时间:2018-09-04 06:27:03

标签: swift

如何创建协议作为函数的参数。

在Android java中,我们可以像这样对接口进行参数设置。

Button.setOnClickListener(new View.OnClicklistener()
{
    @Override
    public void onClick(View v)
    {

    }
});

但是我如何在Swift中做同样的事情。 例如,我有以下协议,在构造协议时如何传递协议。

protocol ButtonListener
{
    func onClick()
}

3 个答案:

答案 0 :(得分:1)

对于实现它应该使用的东西似乎存在误解。可能您想将 closure 作为参数传递给函数。

引用the Swift programming language - Closures

  

关闭是可以包含的功能齐全的功能块   并在您的代码中使用。 Swift中的闭包类似于块   C和Objective-C中的语言,以及其他编程语言中的lambda。

示例:

protocol Foo {
    func myFunc(onClick: (_ myView: UIView) -> Void)
}

class MyClass: Foo {
    func myFunc(onClick: (UIView) -> Void) {
        // ...
    }
}

在这里,我们有一个Foo协议,其中包含myFunc,其协议类型为(UIView) -> Void

因此:

let object = MyClass()

object.myFunc { view in
    // you can access `view` here as:
    view.backgroundColor = ...
    view.frame = ...
}

答案 1 :(得分:0)

在Swift中,这些单方法协议是必需的,因为事件处理程序不是必需的。在Swift中,您可以创建任意类型的 closure 类型。

您的onClick方法可以由闭包类型() -> Void表示(不接受任何参数并返回Void)。除了将setOnClickListener作为方法之外,您只需声明onClick作为属性即可:

var onClick: (() -> Void)?

然后可以像设置其他任何属性一样进行设置:

onClick = {
    print("I am clicked!")
}

要调用onClick,可以先将其拆开以确保其不为空:

if let onClick = self.onClick {
    onClick()
}
// or
onClick?()

如果您熟悉Java 8,则闭包类型有点像功能接口,除了闭包类型有更多的自由度。 Consumer<String>对应于(String) -> VoidFunction<String, Integer>对应于(String) -> Int,依此类推。

答案 2 :(得分:0)

您可以按照协议提供它。

protocol ButtonListener {}

extension ButtonListener where Self: UIView {
    func btnClick() {
        // print func
    }
}