web-dev-qa-db-ja.com

引数付きのブロックを迅速に宣言する方法は?

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!");
}
12
Brandon Foo

Objective-Cブロックに相当するものはSwiftクロージャなので、次のようになります。

{ (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!");
  }
}
14

Swiftのfunctionと同等のブロックを渡す方法はたくさんあります。

3つ見つけた。

これを理解するには、この小さなコードを遊び場でテストすることをお勧めします。

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)

更新:Anonymous関数には2つの特別なケースがあります。

1つ目は、関数のシグネチャを推測できるため、書き換える必要がないことです。

let resultShortAnon = test({return "ANON_" + $0 + "__ANON" })

2番目の特殊なケースは、ブロックが最後の引数である場合にのみ機能します。これは末尾のクロージャーと呼ばれます。

ここに例があります(Swift power)を示すために推定署名とマージされます)

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よりも美しい

7
Francescu

ブロックを変数に格納して後で呼び出す場合は、これをチェックしてください answer

2
Ashok

重要なのは、usernilになる可能性がある場合、それは必須がオプションとして宣言されていることです。したがって:

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

userのタイプには?が含まれ、userオプションの引数nilまたはタイプPFUser)。

オプションを使用しない他の答えは、コンパイルすらできません。

2
GoZoner

これがうまくいくかどうか確認してください。 2日目にこれを学ぼうとするのはおかしい。

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

//それを定義します

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'")
0
Klajd Deda