在我的应用程序中,用户只有在登录时才能执行各种操作。
例如,“喜欢”一张照片。
当尚未登录的用户尝试执行这些操作时,我希望显示登录屏幕,如果登录成功,则立即执行操作。 (如果他们已经登录,则会立即执行操作。)
这是一些伪代码:
// in view controller, user taps like
block variable likeBlock = { likePicture(id) }
if loggedin
perform likeBlock
else
appDelegate.attemptLoginWithViewController(thisViewController)
andSuccess(likeBlock) andFailure(showError)
endif
func likePicture(id:int) {
}
// in appDelegate
attemptLoginWithViewController(vc) andSuccess(likeBlock) andFailure(showError) {
displayLogin, with success (perform likeBlock on vc)
andFailure (perform showError on vc)
}
我无法弄清楚Swift中这种传递块的语法。我该怎么做?
答案 0 :(得分:3)
实际上这可能比你想象的要容易。
如果您声明了likePicture
之类的函数,则可以将该函数分配给变量:
func likePicture(id:int) {
println("Picture \(id) liked")
}
let like = likePicture
if loggedIn {
// then call the stored function
like(1) // prints "Picture 1 liked"
} // etc
因此,除非你想做一些额外的事情,例如在将输入传递给函数之前操作输入,就不需要声明一个块来调用它(在Swift中,这些块被称为闭包表达式)。
由于您可以将函数视为任何其他值,这意味着您可以执行以下操作:
func hatePicture(id:int) {
println("Picture \(id) hated")
}
let action = someUserInput() ? likePicture : hatePicture
// later...
action(1) // performs liking or hating of picture depending which was picked
所需要的只是可以分配给变量的不同函数都具有相同的类型(即签名,声明等),在这种情况下它们都是(Int) -> Void
类型,即采用单个整数参数没有回报。
因此,要声明接收喜欢函数作为参数的函数,您可以执行以下操作:
func attemptLoginWithViewController(vc: WhateverVCType, #onSuccess: (Int)->Void, #onFailure: (Int)->Void) {
// call onSuccess(id) or onFailure(id) depending
}
// and to call it:
attemptLoginWithViewController(vc, onSuccess: likePicture) { println("aargh kerbang") }
(注意,我没有提供失败函数,而是使用尾随闭包,但这里的重点是使用func
定义的函数,使用闭包表达式定义的函数是可互换的)