Как объявить блок с аргументами в 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!");
}

Ответ 1

Эквивалент блоков 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!");
  }
}

Ответ 2

У вас есть много способов предложить блок, эквивалентный функции в 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)

Обновление: для анонимной функции есть 2 специальных случая.

Первая заключается в том, что сигнатура функции может быть выведена, поэтому вам не нужно ее переписывать.

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!")
    }
}

ИМО это красивее, чем в ObjC

Ответ 3

Критически, если user может быть nil, тогда он должен быть объявлен как необязательный. Таким образом:

{ (user: PFUser?, error: NSError) -> {} in
         if (nil == user) ...
    }

отметив, что тип для user включает ?, чтобы указать, что user является необязательным аргументом (либо nil, либо типа PFUser).

Другие ответы, которые не используют опцию, даже не компилируются.

Ответ 4

Посмотрите, работает ли это для вас. Это безумие, пытаясь узнать это на второй день.

let afterSignInAttempt: (PFUser?, NSError) -> Void = { user, error in
    if(!user){
      NSLog("Uh oh.")
    } else {
      user.isNew ? NSLog("Signed up") : NSLog("User Logged in")
    }
}

Ответ 5

Если вы хотите сохранить блок в переменной и вызвать его позже, установите этот ответ

Ответ 6

//определить его

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'")