简体   繁体   中英

Running methods inside a block in Swift

This is probably a dumb question, but still... I'm calling a function inside a block like this:

let makeRocks = SKAction.sequence([SKAction.runBlock(self.createMyNode),<---- here should be () 
                                   SKAction.waitForDuration(0.1, withRange: 0.15)])

func createMyNode() {
    // blabla
}

I don't get it. There should be parentheses after self.createMyNode but this still compiles. How is that so?

You're not in fact calling the function, createMyNode will be called inside SKAction.runBlock , you're simply passing it as an argument.

Take a look at the type SKAction.runBlock accepts, from the SKAction documentation :

class func runBlock(_ block: dispatch_block_t) -> SKAction

And from the GCD documentation :

typealias dispatch_block_t = () -> Void

Therefore, SKAction.runBlock accepts a function (or closure, they're the same thing), which takes no arguments and returns Void ; which is exactly what you're suppling with createMyNode .

With this information it's clear to see why you don't add parentheses after createMyNode - because that would call the function, thus passing Void (the return type of createMyNode ) to SKAction.runBlock , which SKAction.runBlock won't accept.


To clarify, here's another example. Say you had the function:

func takesAFunc(c: (Int, Int) -> Int) -> Void {
    print(c(1, 2))
}

And you wanted to pass in a function that added the two numbers. You could write:

takesAFunc { num1, num2 in
    num1 + num2
}

// Prints: 3

But alternatively, you could just pass in the + operator that accepts Int s - that's a function too. Take a look at the definition:

func +(lhs: Int, rhs: Int) -> Int

That matches the type required by takesAFunc , therefore you can write:

takesAFunc(+) // Prints: 3

runBlock wants a function as parameter which you provide here (so self.createMyNode is only a reference to the function itself).

But you can also wrap the function call in a closure like so:

let makeRocks = 

SKAction.sequence([SKAction.runBlock{ self.createMyNode() },
                                   SKAction.waitForDuration(0.1, withRange: 0.15)])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM