怎么写这个闭包?

时间:2017-10-11 06:11:22

标签: ios swift closures

我想创建一个处理闭包的方法。闭包包含方法调用,我的闭包方法应按顺序执行它们,例如:

when("I tap the Get Coffee button")
{
    _ in
        self.tap(p.button1)
        self.wait(1)
        self.tap(p.button1)
        return true
}

我的(简化)闭包方法:

public func when(_ name:String, closure:(() -> Bool)? = nil)
{
    if let c = closure
    {
        _ = c()
    }
}

这会导致错误:

  

无法转换类型'(_) - >的值_'到期望的参数类型'(()    - >布尔)?“

我不明白需要在闭包参数中定义什么类型才能使其工作。

另外,我想消除闭包中的self.引用,以便它适用于:

when("I tap the Get Coffee button")
{
    _ in
        tap(p.button1)
        wait(1)
        tap(p.button1)
        return true
}

2 个答案:

答案 0 :(得分:1)

删除_ in。这告诉编译器闭包有一个参数,但你的闭包是() -> Bool,也就是说,没有参数。

至于删除self,你必须使闭包不能转义。所有可选的闭包都是@escaping,因此闭包必须是非可选的:

public func when(_ name:String, closure:(() -> Bool)) {
    _ = closure()
}

when("I tap the Get Coffee button") {
    tap(p.button1)
    wait(1)
    tap(p.button1)
    return true
}

转义关闭可以创建所有权周期(内存泄漏),这就是为什么每次使用selfself都必须被捕获)必须是明确的。

答案 1 :(得分:1)

我想我得到了你想要的东西。我可能错了。

由于您要使用tapwait而不使用self,因此您需要在闭包的参数列表中使用这些内容。

tap的签名似乎是(UIButton) -> ()wait的签名似乎是(Int) -> ()

所以,将这两个闭包传递给闭包。

由于类型变得非常复杂,我建议你使用类型别名:

 typealias WhenHandler = ((UIButton) -> (), (Int) -> ()) -> Bool

您的when方法可以是:

public func when(_ name:String, closure: WhenHandler)

您应该将self.tapself.wait传递给closure方法中的when,如下所示:

if let c = closure
{
    _ = c(self.tap, self.wait)
}

现在,您可以像这样致电when

when("I tap the Get Coffee button")
{
    tap, wait in
        tap(p.button1)
        wait(1)
        tap(p.button1)
        return true
}