Skip to content

Instantly share code, notes, and snippets.

@shrawan2015
Created December 18, 2017 15:27
Show Gist options
  • Save shrawan2015/e53cd93f4dd8b23a421cb503557ddaca to your computer and use it in GitHub Desktop.
Save shrawan2015/e53cd93f4dd8b23a421cb503557ddaca to your computer and use it in GitHub Desktop.
//: Playground - noun: a place where people can play
import UIKit
var str = "Hello, playground"
let queue = DispatchQueue(label: "queue.1")
//To add some context, a queue is a block of code that can be run synchronously or asynchronously in either the main or background thread.
//When we use a queue, we can either use a global one that is provided to us by Apple, or we can create our own custom ones. It should be noted that global queues should be used cautiously as we wouldn’t want to abuse them.
//// Background thread
//queue.sync {
// for i in 0..<10 {
// print("🔷", i)
// }
//}
//// Main thread
//for i in 20..<30 {
// print("⚪️", i)
//}
//let our app know how to prioritize our tasks. This specification is referred to as Quality of Service (QOS)
//let firstQueue = DispatchQueue(label: "queue1", qos: DispatchQoS.userInitiated)
//let secondQueue = DispatchQueue(label: "queue2", qos: DispatchQoS.userInitiated)
//firstQueue.sync {
// for i in 0..<10 {
// print("🔷", i)
// }
//}
//secondQueue.sync {
// for i in 20..<30 {
// print("⚪️", i)
// }
//}
//let randomQueue = DispatchQueue(label: "randomQueue", qos: .utility)
// To run the process in the concurrent thread
//let randomQueue = DispatchQueue(label: "randomQueue", qos: .utility, attributes: .concurrent)
//
//randomQueue.async {
// for i in 0..<10 {
// print("🔷", i)
// }
//}
//randomQueue.async {
// for i in 20..<30 {
// print("⚪️", i)
// }
//}
//randomQueue.async {
// for i in 30..<40 {
// print("🔶", i)
// }
//}
//Earlier I mentioned that instead of creating custom queues, the system can provide us with background dispatch queues called global.
let globalQueue = DispatchQueue.global()
globalQueue.async {
// Do something here
}
//In addition to using global queues, we can also access main queue depending on our needs.
DispatchQueue.main.async {
// Do something here
}
//Main queues are perfect for updating UI and fetching our images, whereas any other heavy task should run on the background thread.
//Overall, GCD allows us to multitask in our apps and run code that is synchronous or asynchronous, and serial or concurrently, depending on how we’d like our app to execute certain blocks of code. We can create custom queues, or use Apple’s global queues to perform these various tasks, and the main thread should always be dedicated to updated the UI.
////////BOB THE DEVELOPER //////////////
//The code below tells how to access your main (heavy) and background (lightweight) objects (workers).
let main = DispatchQueue.main
let background = DispatchQueue.global()
//However, if the manager needs to get another 97 pounds, he could simply create an object (lightweight) as shown below.
let helper = DispatchQueue(label: "construction_worker_3")
func doSyncWork() {
background.sync { for _ in 1...3 { print("Light") } }
for _ in 1...3 { print("Heavy") }
}
// main
doSyncWork()
// Light
// Light
// Light
// Heavy
// Heavy
// Heavy
//If the light dude (background) runs the block synchronously, then it prevents any dudes from running at the same time until the code block is finished. It’s a bottleneck.
print("\n \n this is async code \n \n \n ")
func doAsyncWork() {
background.async { for _ in 1...3 { print("Light") } }
for _ in 1...3 { print("Heavy") } } // main
doAsyncWork()
// Light
// Heavy
// Heavy
// Light
// Heavy
// Light
//Interestingly though, the main queue and the background queue do the job at the same time. Now, let’s create our own custom construction workers.
print("\n \n this is custom queue code \n \n \n ")
let asianWorker = DispatchQueue(label: "construction_worker_1")
let brownWorker = DispatchQueue(label: "construction_worker_2")
func doLightWork() {
asianWorker.async { for _ in 1...10 { print("👷") } }
brownWorker.async { for _ in 1...10 { print("👷🏽") } } }
//doLightWork()
// 👷, 👷🏽, 👷, 👷🏽, 👷, 👷🏽, 👷, 👷🏽, 👷...
//For the longest time I thought asynchronous was synonymous to running something on a background thread, while synchronous meant on the main thread (blocking UI updates and interactions). I understand that not running on the main thread for expensive actions is because it doesn't allow UI actions to occur as the main thread is occupied, but why is synchronous troublesome?
//When you invoke something synchronously, it means that the thread that initiated that operation will wait for the task to finish before continuing. Asynchronous means that it will not wait.
//However, it's since came to my attention that you can make asynchronous calls on the main thread, and synchronous calls on background threads.
///////synchronous calls on background threads. //// how we can do this.
//Having said that, when people suggest that you perform some slow or expensive process asynchronously, they are implicitly suggesting not only that you should run it asynchronously, but that you should do that on a background thread. The goal is to free the main thread so that it can continue to respond to the user interface (rather than freezing), so you are dispatching tasks to a background thread asynchronously.
/////"Synchronous" essentially means "in order." Basically, when you do a synchronous operation, everything that comes later has to wait for the operation to finish before they can start.
//////Conversely, "asynchronous" more or less means "not in order." When you do something asynchronously, the following code can immediately run and the asynchronous operation will be run…sometime. It might be run in parallel with the rest of the code on another thread. It might simply be scheduled for some other time on the same thread.
///Before we get into using GCD, we have to learn about concurrency. Tasks can be executed serially or concurrently (think of a task as just a closure in Swift). A sequence of tasks is executed serially if the tasks are executed one after the other, with the next task waiting for the previous one to finish. On the other hand, a sequence of tasks is executed concurrently if multiple tasks can be executed at the same time. Imagine a bank with one bank teller and a line of people. If we wanted to go through the people in line serially, we would have one long line of people. In a concurrent setup, we would have multiple lines to one bank teller.
//Parallelism requires concurrency, but concurrently does not imply parallelism.
////////important ///////////
//A function is synchronous if it returns after finishing its task. A function is asynchronous if it returns immediately and sends its task elsewhere to be completed.
////There are a few more terms that we should be familiar with when discussing concurrency. The first is the distinction between synchronous and asynchronous code. Let’s suppose that the code is wrapped in a function, which is often the case. A function is synchronous if it returns after finishing its task. A function is asynchronous if it returns immediately and sends its task elsewhere to be completed. It does not wait for the task to complete to continue execution.
///This distinction is important because synchronous functions block the main thread of execution so our user will not be able to interact with our app while a synchronous function is executing. These functions should be kept fairly small and execute fair quickly. For longer tasks or tasks whose time is unpredictable, we should use an asynchronous function and queue the work. These functions do not block the main thread of execution, and our user can still interact with our app while they wait.
////The last thing we have to discuss is the different queues that Apple provides us out-of-the-box. We offload tasks to these queues. Each queue has its Quality of Service (QoS) class/category, and we have to decide which QoS class best fits our task.
///Note that these queues are system global queues; our tasks won’t be the only tasks in these queues! Also it is important to note that these queues are concurrent queues. Apple does provide us with a serial queue called the main queue. This is the queue that we use to update our UI, for example, and, in fact, it is the only queue in which we can update any UI elements.
///Now let’s create an action to the button so that we can execute the code when we click on the button. To execute code in the main serial queue, we call DispatchQueue.main.async and use a trailing closure. The async method does not take any parameters except for a closure so we can even omit the empty parentheses! (The [unowned self] in is to ensure we’re using good memory management)
func trailingClosure(firstName:String,secondName:String ,closure :(String) -> (String)){
closure(firstName + secondName)
}
trailingClosure(firstName: "shrawan", secondName: "sharma") { (finalName) in
print("finalname ", finalName)
return finalName
}
var fullnumber = trailingClosure(firstName: "sks", secondName: "ssssss") { (fullname) -> (String) in
return fullname
}
//No use of the return type
//print("fullnumber",fullnumber)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment