如何在swift中声明带参数的块?

时间:2014-06-03 23:14:02

标签: ios objective-c-blocks swift

很难弄清楚如何使用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!");
}

6 个答案:

答案 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可选参数nilPFUser类型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'")