The Swift equivalent of an (Objective-)C block is called a closure. There's a whole chapter about them in The Swift Programming Language book.
Depending on the context where you use a closure, you can declare/use it with very concise syntax. For example, a method that takes a completion handler whose signature is (success: Bool, error: NSError) - > Void
can be called like this:
someMethod(otherParameters: otherValues, completionHandler:{ success, error in
if !success { NSLog("I am a leaf on the wind: %@", error) }
})
There's also a trailing closure syntax that reads nicely in cases where a closure essentially provides flow control. And you can drop the parameter names when you want to be really brief (at some cost to readability, but that's okay in some obvious cases like the below). Often a return
statement is implicit, too.
myArray.sort { $0 < $1 }
let squares = myArray.map { value in
value * 2
}
Swift itself doesn't have anything for asynchronous requests, so you use existing API for that. You can use the trailing closure syntax, though:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
// do some async stuff
NSOperationQueue.mainQueue().addOperationWithBlock {
// do some main thread stuff stuff
}
}
In most cases, you don't need to worry about creating reference cycles with Swift closures the way you do with ObjC blocks. To put it simply, the capture semantics are similar enough to "just work" the way you want it to for most stuff, but different enough that the common patterns for block/closure uses (e.g. dispatch to background/main thread and referencing self
's properties) don't cause cycles.
Cycles are still possible, though, and there is a solution for them. This answer's a bit long already, so check out Strong Reference Cycles for Closures in the docs for the complete explanation.