【问题标题】:Swift Passing Closure With Params使用参数快速传递闭包
【发布时间】:2014-06-13 14:40:54
【问题描述】:

目前,我将一个闭包作为一个对象的属性传递,该对象不接受任何参数且没有返回值,如下所示:

class MyClass {
    var myClosureProperty: (() -> ())? {
            didSet {
                doSomeActionWhenClosureIsSet()
            }
    }
}

var instanceOfMyClass = MyClass()
instanceOfMyClass.myClosureProperty = {
    // do some things here...
}

到目前为止,效果很好。在设置此闭包以在 MyClass 的实例中使用时,我希望能够传入一个参数。我正在寻找类似下面的东西,尽管我确定语法不正确:

class MyClass {
    var myClosureProperty: ((newString: String) -> ())? {
            didSet {
                doSomeActionWhenClosureIsSet(newString)
            }
    }

    func doSomeActionWhenClosureIsSet(stringParam: String) -> () {
        // create a button with the stringParam title...
    }
}

var instanceOfMyClass = MyClass()
instanceOfMyClass.myClosureProperty = {("Action")
    exampleFunction()
}

我将如何向这个闭包传递一个可以在 MyClass 内部使用的参数 - 即一个可以在属性本身的 didSet 部分中使用的值,如第二个示例所示?

编辑:这就是最终对我有用的东西:

class MyClass {
        var myClosurePropertyWithStringAndAction: (buttonName: String, closure: (() -> ()))? {
            didSet {
                  let buttonTitle = myClosurePropertyWithStringAndAction!.buttonName
                  createButtonWithButtonTitle(buttonTitle)
            }
         }

        func createButtonWithButtonTitle(buttonTitle: String) -> () {
             // here I create a button with the buttonTitle as the title and set
             // handleButtonPressed as the action on the button
        }

        func handleButtonPressed() {
            self.myClosurePropertyWithStringAndAction?.closure()
        }
    }
}

这是我在实例上的调用方式:

instaceOfMyClass.myClosurePropertyWithStringAndAction = ("Done", {
    // do whatever I need to here
})

【问题讨论】:

  • 您是否只是在寻找使用输入参数定义闭包的语法?你的问题有点不清楚
  • 抱歉,在编辑时按退格键,我返回了一个页面,当我回来时,一些更改不存在。让我用实际问题编辑我的帖子。
  • 我认为您正在尝试做的事情存在一些逻辑问题...newString 是闭包的输入参数的名称。设置闭包时,该值为 unknown。您的didSet 无法访问它,因为当您调用闭包并实际执行它时,该值将被传入。
  • 同样,当您设置myClosureProperty 时,将SUCCESS 传递给闭包是没有意义的,因为您没有调用它,您只是在定义关闭。
  • 这就是我正在尝试做的事情,也许它会更有意义,也许我选择的带有“成功”的字符串令人困惑......我想将一个字符串和一个动作传递给 MyClass。当我在 MyClass 的实例上设置闭包属性时,我想调用一个函数,该函数使用该字符串作为标题创建一个按钮,并且当按下按钮时,我希望运行闭包中定义的操作。在上面的示例中,当 MyClass 出现在屏幕上(一个 UIView)时,我希望有一个按钮显示“Action”,并且当按下该按钮时调用函数 exampleFunction()。

标签: ios closures block swift


【解决方案1】:

由于您尝试设置 pass 2 件事,一个闭包和一个按钮名称,您将无法使用简单的闭包设置器来做到这一点。

你的限制是这两个东西是相互依赖的,所以你必须要么都设置,要么都不设置。

首先,将newString 添加到您的闭包中并不是您认为的那样。它是一个参数,因此您可以在调用它时将字符串传递给闭包,它不是在定义闭包时传递字符串的方法。

做你想做的事情的“快速方式”可能是将它定义为一个元组。您可以命名元组中的值,以便它可以按照您的意愿工作。试试这样:

class MyClass {
    var stringAndClosure: (buttonName: String,closure: (() -> ()))? {
        didSet {
            //create button named buttonName
            let name = stringAndClosure!.buttonName
        }
    }
}

let instanceOfMyClass = MyClass()
instanceOfMyClass.stringAndClosure =  ("Action",{ exampleFunction() })

【讨论】:

  • 这个可能更合适,我会测试一下。
  • 我在尝试访问 didSet 中的 buttonName 时遇到了未解决的标识符错误...
  • @Mike 因为它是可选的,你必须打开它,我会编辑
【解决方案2】:

您应该使用in 关键字在闭包中传递参数

{ (someString: String) -> Bool in
    //do something with someString
    return true
}

【讨论】:

    【解决方案3】:

    不要认为是可能的......你可以这样做:

    class MyClass{
        var myClosureProperty: (() -> String)?
        {
            didSet
            {
                doSomeActionWhenClosureIsSet(myClosureProperty!())
            }
        }
        func doSomeActionWhenClosureIsSet(stringParam: String) -> ()
        {
            println("it worked: " + stringParam) // hopefully this would print "it worked: SUCCESS"
        }
    }
    

    【讨论】:

    • 这是为我做的,我将添加一个具有更具体实现的编辑,即使它看起来有点违反直觉 - 它有效......
    • @Mike 也许我误解了你的目的......但这会在你设置后立即调用你的关闭。那是你要的吗?这个答案使用你的闭包的返回值,我不确定这是你想要的,因为你想创建一个调用闭包的按钮,据我了解
    • @Jack Wu 的回答对我来说看起来更好:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多