For now, don't trust autocomplete to insert the code you need — it drops in signatures from the "header", but a block signature is not the same as the declaration you need when inserting your own closure for a block parameter.
The formal way to write a closure would be to replicate the signature inside braces, adding local parameter names and using the in
keyword to mark the start of the closure body:
self.enumerateChildNodesWithName("enemy", usingBlock: {
(node: SKNode!, stop: UnsafeMutablePointer <ObjCBool>) -> Void in
// do something with node or stop
})
But Swift's type inference means you don't have to write that much. Instead, you can just name the parameters, because their type (as well as the closure's return type) is known:
self.enumerateChildNodesWithName("enemy", usingBlock: {
node, stop in
// do something with node or stop
})
You can also use trailing closure syntax:
self.enumerateChildNodesWithName("enemy") {
node, stop in
// do something with node or stop
}
(You can even drop the local parameter names and refer to parameters by position — e.g. $0
for node
— but here isn't a great place to do that because it makes your code far less readable. It's best to reserve $0
and friends for closures where it's blindingly obvious what the parameters are, like the closures you use with map
and sort
.)
See Closures in The Swift Programming Language for further explanation.
Also, because stop
is an UnsafeMutablePointer
, the syntax for using it is a bit different than in ObjC: set stop.memory = true
to break out of enumeration.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…