Closure
Closure is a first class citizen of the language
- assign them to variables or constants,
- put then inside arrays or dictionaries
- return them as the result of a function or closure
- and even receive them as parameters of another function or closure!
let f = { (x:Int) -> Int in
    return x + 42
}
f(89)
let closures = [
    f,                                  // our previous closure
    {(x:Int) -> Int in return x * 2},   // a new Int -> Int closure
    {x in return x - 8},                // no need for the type of the closure!
    {(x:Int) in x * x},                 // no need for return if only one line
    {$0 * 42}                           // access parameter by position instead of name
]
for fn in closures {
fn(42)
}
Functions and closures are the same thing
Actually, when the compiler finds a function declaration such as foo, it will take the following steps:
- Create a closure that takes an Int and returns 42 plus that Int.
- Then, assigns this closure to a constant called foo
func foo(x:Int) -> Int {
    return 42 + x
}
let bar = { (x: Int) -> Int in
    return 42 + x
}
add a few functions to an array and then call them
func larry(x:Int) -> Int {
    return x * x
}
func curly(n:Int) -> Int {
    return n * (n - 1)
}
func moe(n:Int) -> Int {
    return n * (n - 1) * (n - 2)
}
var stooges = [larry, curly, moe]
for stooge in stooges {
    stooge(42)
}
stooges.append(bar)
for each in stooges {
    each(42)
}
Typealias & Capture value
typealias IntMaker = (Void) -> Int
Functions and closure capture variables defined before the closure or function is defined.
func makeCounter() -> IntMaker {
    var n = 0
    // Functions within functions?
    // Yes we can!
    func adder() -> Integer {
        n = n + 1
        return n
    }
    return adder
}
let counter1 = makeCounter()
let counter2 = makeCounter()
counter1() //1
counter1() //2
counter1() //3
each closure has its own copy of the environment (the values of all variables that were captured).
counter2() //1
GCD
Hiding threads
- Threads are inherently complex and dangerous 
- GCD makes asynchronous programming easier and safer by hiding threads within the concept of a queue of closure from the developer 
- Blades are inherently dangerous ,add handles to make for safer knives 
Types of queues
Serial or synchronous queue - predictable
- Every closure gets to run when it reaches the end of the queue 
- The order in which closures run is predictable 
- Still have concurrency ,each queue will run on its own threads and will not block each other 
Concurrent or Asynchronous queue - unpredictable
- Have several threads pickup closures at any point of the queue for running 
- The order in which closures run is not predictable 
Main queue
- handles the UI of your app 
- You should never run code that blocks on this queue 
Main function in GCD
create a queue
Represents a queue
dispatch_queue_t
Ceate a queue from scratch,To specify serial, just pass dispatch_queue_serial or nil
dispatch_queue_create(name,serial/concurrent)
Global queues
Use existing one queue instead of creating new queues
QOS_CLASS_USER_INTERACTIVE //top priority 
QOS_CLASS_USER_INITIATED   //regular priority 
QOS_CLASS_BACKGROUND    //low
QOS_CLASS_UTILITY //lowes 
access those global queues with function
dispatch_get_global_queue
Main queue
get the main queue
dispatch_get_main_queue()
Add a closure to a queue
- the code inside the queue will run sometime in the immediate future
- the exact time will depend on how many closures already waiting in the queue and the priority of the queue
- dispatch_async adds your closures to each queue and return imediately
Add a closure to a queue
dispatch_async ()
Example 1
let q = dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE,0)
//Imediately return and add the block to the q ,then run in the near future 
dispatch_async(q){
    () -> Void in
    print("tic")
}
print ("tac") //this run first
Example 2
//cannot predict order the code run below of each queue
let q1 = dispatch_queue_create("queue1",nil)
let q2 = dispatch_queue_create("queue1",nil)
let q3 = dispatch_queue_create("queue1",nil)
dispatch_async(q1){ ()->Void in
print(1)
}
dispatch_async(q2){ ()->Void in
print(2)
}
dispatch_async(q3){ ()->Void in
print(3)
}
print("end") //run first
UIKIT & CoreData
- when the framework can run in the background it is said to be thread safe 
- cannot run anything from UIKit in the background 
//maybe crash , uikit should run in Main queue
let downloadQueue = dispatch_queue_create("download",nil)
dispatch_async(downloadQueue){()-> Void in 
let imgData = NSData (contentsOfURL:url!)
let image = UIImage(data:imgData!)
self.photoViewimage = image
}
Synchronous download
// Get the URL for the image
let url = NSURL(string: BigImages.seaLion.rawValue)
// Obtain the NSData with the image
let imgData = NSData(contentsOfURL: url!)
// Turn it into a UIImage
let image = UIImage(data: imgData!)
// Display it
photoView.image = image
Refactor code by if-let
if let url = NSURL(string: BigImages.seaLion.rawValue),
    let imgData = NSData(contentsOfURL: url),
    let image = UIImage(data: imgData){
    // Display it
    photoView.image = image
}
Asynchronous download
Not all of UIkit is thread and save.There are a few exceptions, such as UIImage
All the visual stuff, the views are unsaved
if name end view, it must be main queue 
@IBAction func simpleAsynchronousDownload(sender: UIBarButtonItem) {
        let url = NSURL(string: BigImages.shark.rawValue)
        // create a queue
        let downloadQueue = dispatch_queue_create("download", nil)
        // add a closure that encapsulates the blocking operation
        // run it asynchronously: some time in the near future
        dispatch_async(downloadQueue) { () -> Void in
            // Obtain the NSData with the image
            let imgData = NSData(contentsOfURL: url!)
            // Turn it into a UIImage
            let image = UIImage(data: imgData!)
            // Run the code that updates the UI in the main queue!
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                // Display it
                self.photoView.image = image
            })
        }
    }
Completion Closure
It is a good practice to make sure that always all your completion handlers run in the main queue
    func withBigImage(completionHandler handler: (image: UIImage) -> Void){
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { () -> Void in
        // get the url
        // get the NSData
        // turn it into a UIImage
        if let url = NSURL(string: BigImages.whale.rawValue), let imgData = NSData(contentsOfURL: url), let img = UIImage(data: imgData) {
            // run the completion block
            // always in the main queue, just in case!
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                handler(image: img)
            })
        }
    }
}
Async & Sync
doesn’t wait for the closure to finish ,and moves on Always use until you know very well what you are doing
dispatch_async()
won’t return immediately.waits until the closure is done ,could easily get stalled!
dispatch_sync()