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