which GCD queue to put firebase operations in? swift 4 - ios

Which queue is the best to place firebase operations? Is it the background queue, the main queue, or does it depend on how heavy the operation is?

It sort of depends on how much work you're doing in Firebase.
You can start out doing everything on the main thread. If you notice your UI lagging, switch to a background queue, and wrap all of your UI calls in a Dispatch.async call to the main thread.

Related

How to ensure that some code runs on same background thread with runloop

I am using realm in an iOS app.
I am calling realm methods in a background thread. Realm objects can be used only in the thread where it was created.
This means that I have to ensure that all the code related to accessing realm objects happen on the same thread. This question has been answered here - How to ensure to run some code on same background thread?
The background thread has no runloop and hence realm objects do not get refreshed automatically.
Can any one point out how to create a background thread with a runloop so that the code blocks can be executed on the same background thread with runloop?
Not knowing more about your use case (or Realm for that matter!) a suggestion - do you need to use a background thread at all?
Seems that some suggest the Main UI Thread is fine most of the time and may simplify your life.
Is it acceptable to load Realm objects in the main ui thread?

Are completion handler closures always running in the background thread?

Completion handler closures are common in iOS development, such as dataTask(with:completionHandler:) in the URLSession class.
The UI engine is managed by the main thread, the API calls by URLSession are run under the background thread and must be dispatched to the main thread if a UI update is needed in the handler.
Question 1:
Do all completion handler closures from the iOS framework run in the background thread?
Question 1.1:
Do all escaping closures, for example, created by developers, run in the background thread?
Question2:
I've seen up to 8 threads in the iPhone X simulator. Which one is the main thread and which one is the background thread in ios? Do they have different priorities and computational power?
Keep in mind that you are really asking about queues and threading more than completion handlers and closures. Code of any type is executed on a queue (which consists of one or more threads). There is nothing special about completion handler closures in this regard.
Q1 - Most iOS SDK provided completion handlers are called on a background queue but don't make that assumption unless the documentation specifically states what queue it is called on. Even URLSession can be configured to run on a specific queue, including the main queue.
Q1.1 - Closures that you write are run on whatever queue you call them from. There is no magic that makes them run on a background queue.
Q2 - The first thread is always the only thread of the main queue. All other threads are from background queues. Each thread can have whatever priority is was given based on the properties of its queue.
You should review the Dispatch documentation for further details, especially DispatchQueue.

Do we need to update UI in main thread or in main queue?

I read a lot many articles which specifies that we need to update the UI in the main thread however whenever I update my UI is always the code.
DispatchQueue.main which in return gives me the Queue not thread. How exactly I would access the thread or both are same ?
Imagine a train station where the number of the train is the same as the number of the platform that it leaves from.
So if you want the #1 train, you stand on #1 platform. You cannot get on the train without first standing on the platform. Everyone else who wants to get on this train also stands on the platform to wait for their chance to get on the train.
The train is the thread. The platform is the queue.
If you want to get on the main thread, get on the main queue.
From Dispatch Queues in the Concurrency Programming Guide:
Main dispatch queue
The main dispatch queue is a globally available serial queue that executes tasks on the application’s main thread. This queue works with the application’s run loop (if one is present) to interleave the execution of queued tasks with the execution of other event sources attached to the run loop. Because it runs on your application’s main thread, the main queue is often used as a key synchronization point for an application.
Generally, GCD maintains a pool of threads, and there is no 1-1
relationship between dispatch queues and threads. But the main queue
is special: it is tied to the main thread, all items dispatched
to the main queue are executed on the main thread. (The same is
true for OperationQueue.main.)
Dispatching code to DispatchQueue.main (or OperationQueue.main)
ensures that it is executed on the main thread, and synchronized with
other UI updates.
In this sense, the terms “execute on the main thread” and
“execute on the main queue” are often used interchangeably.
DispatchQueue manages the execution of the code on a specific thread.
From Apple documentation:
DispatchQueue manages the execution of work items. Each work item
submitted to a queue is processed on a pool of threads managed by the
system.
So, when you call
DispatchQueue.main.async {
//your code
}
This code is submitted to the main queue which in turn runs on the Main thread.
//main thread
DispatchQueue.main.async
{
//eg.
tableview.reloadData()
// here you update your UI.
}

Suspending and resuming Grand Central Dispatch thread

I am using Grand Central Dispatch to run a process in background. I want know how can i suspend, resume and stop that background thread. I have tried
dispatch_suspend(background_thread);
dispatch_resume(background_thread);
but these functions doesn't help me, it keeps on running. Please someone help me.
You seem to have some confusion. Direct manipulation of threads is not part of the GCD API. The GCD object you normally manipulate is a queue, not a thread. You put blocks in a queue, and GCD runs those blocks on any thread it wants.1
Furthermore, the dispatch_suspend man page says this:
The dispatch framework always checks the suspension status before executing a block, but such changes never affect a block during execution (non-preemptive).
In other words, GCD will not suspend a queue while the queue is running a block. It will only suspend a queue while the queue is in between blocks.
I'm not aware of any public API that lets you stop a thread without cooperation from the function running on that thread (for example by setting a flag that is checked periodically on that thread).
If possible, you should break up your long-running computation so that you can work on it incrementally in a succession of blocks. Then you can suspend the queue that runs those blocks.
Footnote 1. Except the main queue. If you put a block on the main queue, GCD will only run that block on the main thread.
You are describing a concurrent processing model, where different processes can be suspended and resumed. This is often achieved using threads, or in some cases coroutines.
GCD uses a different model, one of partially ordered blocks where each block is sequentially executed without pre-emption, suspension or resumption directly supported.
GCD semaphores do exist, and may suit your needs, however creating general cooperating concurrent threads with them is not the goal of GCD. Otherwise look at a thread based solution using NSThread or even Posix threads.
Take a look at Apple's Migrating Away from Threads to see if your model is suited to migration to GCD, but not all models are.

Difference between dispatch_get_main_queue and dispatch_get_global_queue

I have just started working on iOS and have been going through Apple Reference material on GCD. dispatch_get_global _queue returns a concurrent queue to which one can submit a block to be executed.
However, we can achieve the same using dispatch_get_main_queue as well, right? Then, what exactly is the difference between dispatch_get_global_queue and dispatch_get_main_queue?
The global queue is a background queue and executes its blocks on a non-main thread. The main queue executes its blocks on the main thread.
You should put background work that does not involve changes to the user interface on the global queue, but use the main queue when the blocks make changes to the user interface. A very common pattern, for example, is to execute a "work" block on the global queue, and to have the work block itself dispatch back to the main queue to update a progress indicator.
dispatch_get_main_queue - should be used when you want to manipulate UI elements.
(It gets a background queue that you can dispatch background tasks that are run asynchronously... it won't block your user interface)
dispatch_get_global_queue - Can be used for network calls/core data.

Resources