很难弄清楚如何使用swift正确声明/使用块。 什么是以下代码的快速等价物?
感谢。
^(PFUser *user, NSError *error) {
if (!user) {
NSLog(@"Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew) {
NSLog(@"User signed up and logged in through Facebook!");
} else {
NSLog(@"User logged in through Facebook!");
}
答案 0 :(得分:14)
Objective-C块的等价物是快速闭包,因此它将如下所示
{ (user: PFUser, error: NSError) in
if (!user) {
println("Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew) {
println("User signed up and logged in through Facebook!");
} else {
println("User logged in through Facebook!");
}
}
答案 1 :(得分:7)
你有很多方法可以在Swift中传递一个等效于函数的块。
我发现了三个。
为了理解这一点,我建议你在游乐场测试这段小代码。
func test(function:String -> String) -> String
{
return function("test")
}
func funcStyle(s:String) -> String
{
return "FUNC__" + s + "__FUNC"
}
let resultFunc = test(funcStyle)
let blockStyle:(String) -> String = {s in return "BLOCK__" + s + "__BLOCK"}
let resultBlock = test(blockStyle)
let resultAnon = test({(s:String) -> String in return "ANON_" + s + "__ANON" })
println(resultFunc)
println(resultBlock)
println(resultAnon)
更新:匿名功能有两种特殊情况。
首先,可以推断出功能签名,因此您不必重写它。
let resultShortAnon = test({return "ANON_" + $0 + "__ANON" })
第二种特殊情况仅在块是最后一个参数时起作用,它被称为尾随闭包
这是一个例子(与推断签名合并以显示Swift权力)
let resultTrailingClosure = test { return "TRAILCLOS_" + $0 + "__TRAILCLOS" }
最后:
使用所有这些功能我所做的就是混合尾随闭包和类型推断(为了便于阅读命名)
PFFacebookUtils.logInWithPermissions(permissions) {
user, error in
if (!user) {
println("Uh oh. The user cancelled the Facebook login.")
} else if (user.isNew) {
println("User signed up and logged in through Facebook!")
} else {
println("User logged in through Facebook!")
}
}
IMO比ObjC更美丽
答案 2 :(得分:2)
重要的是,如果user
可以是nil
,则必须声明为可选。因此:
{ (user: PFUser?, error: NSError) -> {} in
if (nil == user) ...
}
注意user
的类型包含?
,表示user
是可选参数(nil
或PFUser
类型1}})。
其他不使用Optional的答案甚至都不会编译。
答案 3 :(得分:2)
看看这是否适合您。在第二天学习这个很疯狂。
let afterSignInAttempt: (PFUser?, NSError) -> Void = { user, error in
if(!user){
NSLog("Uh oh.")
} else {
user.isNew ? NSLog("Signed up") : NSLog("User Logged in")
}
}
答案 4 :(得分:2)
如果您想将块存储在变量中并稍后调用它,请检查此answer
答案 5 :(得分:0)
//定义
class IDDBlockTime {
// return time elapsed in milliseconds
//
static func timeSpent(_ block: (Void) -> Void) -> TimeInterval {
let methodStart = Date()
block()
return Date().timeIntervalSince(methodStart) * 1000.0
}
}
//使用它
let timeSpent = IDDBlockTime.timeSpent {
// lines of code you want to measure
//
self.doSomethig()
}
print("timeSpent: '\(timeSpent) ms'")