【问题标题】:How to write this closure?这个闭包怎么写?
【发布时间】:2017-10-11 06:11:22
【问题描述】:

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

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
}

【问题讨论】:

  • 将闭包设为可选有什么意义?你会在没有闭包的情况下调用when 方法吗?
  • 如果你只是忽略返回值,为什么还要定义一个返回类型为Bool的闭包呢?
  • @maddy 这两个都有原因,因此我写了(简化)。

标签: ios swift closures


【解决方案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 将被捕获)都必须是显式的。

【讨论】:

  • 是的,我知道,但我仍然想知道如何更改它,以便它为此代码使用正确的参数类型。还有,去掉.self怎么样?
  • 所以这是可选的?感谢您的提示!
【解决方案2】:

我想我得到了你想要的。不过我可能错了。

由于您想在不使用self 的情况下使用tapwait,因此您需要在闭包的参数列表中使用它们。

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

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

由于类型越来越复杂,我建议你使用类型别名:

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

而您的when 方法可以是:

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

您应该像这样在when 方法中将self.tapself.wait 传递给closure

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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-09
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2013-06-18
    相关资源
    最近更新 更多