Take our short survey. Stack Overflow for Teams — Collaborate and share knowledge with a private group. Create a free Team What is Teams? Collectives on Stack Overflow. Learn more. What is purpose of dispatch sync? Ask Question. Asked 6 years, 2 months ago. Active 2 years, 10 months ago. Viewed 4k times. Improve this question. Stefan Stefan 1, 14 14 silver badges 33 33 bronze badges. Add a comment. If you create your own concurrent dispatch queue, you can tell the system what the QoS is via its initializer:.
The OS will pay attention to what type of tasks are being submitted to the queue and make changes as necessary. Not only that, but all the operations enqueued will also have their priority raised as well.
If the current context is the main thread, the inferred QoS is. Dispatch queues provide both sync and async methods to add a task to a queue.
There are two key points you should take away from the above code sample. Strongly capturing self in a GCD async closure will not cause a reference cycle e. For instance, if you make a network request from a view controller that has been dismissed in the meantime, the closure will still get called. If you capture the view controller weakly, it will be nil.
However, if you capture it strongly, the view controller will remain alive until the closure finishes its work. Keep that in mind and capture weakly or strongly based on your needs. Second, notice how updates to the UI are dispatched to the main queue inside the dispatch to the background queue. Note : You should never perform UI updates on any queue other than the main queue. Use extreme caution when submitting a task to a dispatch queue synchronously.
Note : Never call sync from the main thread, since it would block your main thread and could even potentially cause a deadlock. Time to see an actual example!
Open up the Concurrency. Build and run the app. If you try to scroll the screen while the images are loading, either nothing will happen or the scrolling will be very slow and choppy, depending on the speed of the device you are using.
Open up CollectionViewController. When the view loads, it just grabs a static list of image URLs to be displayed. The code looks simple enough, and it is what most starting iOS developers would do to download an image, but you saw the results: a choppy, underperforming UI experience!
Unless you slept through the previous pages of explanation, you know by now that the work to download the image, which is a network call, needs to be done on a separate thread from the UI. Mini-challenge : Which queue do you think should handle the image download?
Take a look back a few pages and make your decision. Did you pick either. The proper choice here is to use the. Create a new method in CollectionViewController that starts off like so:. Begin by determining which URL should be loaded. Add the following code inside the async closure:. Once you know the URL to load, you can use the same Data initializer you previously used. It doesn't wait for the block of work to start its execution. The async execute: method returns as soon as the block of work has been submitted to the global dispatch queue.
This means that the second print statement is executed on the main thread immediately after invoking the async execute: method. Grand Central Dispatch decides when it's most opportune to execute the block of work on a background thread. The size of the remote resource is printed to the console after the data for the remote resource has been downloaded. It's also possible to execute the block of work synchronously by passing the block of work to the sync execute: method.
Let's try it out. Replace the async execute: method with the sync execute: method and execute the contents of the playground to see the difference. The output in the console clearly highlights the differences between the async execute: method and the sync execute: method.
The sync execute: method doesn't immediately return control to the thread from which the sync execute: method is invoked. In other words, the sync execute: method blocks the thread from which it is invoked, that is, the calling thread. Control is returned after the block of work has finished executing. This is better known as synchronous execution.
Let me illustrate what happens. The main thread executes the first print statement. It then dispatches a block of work to a global dispatch queue for synchronous execution. Because the block of work is executed synchronously, the calling thread, the main thread in this example, is blocked until the block of work has finished executing.
The sync execute: method returns control to the main thread after downloading the data for the remote resource and printing the size of the Data instance to the console. The last print statement is executed immediately after the sync execute: method returns control to the main thread.
That explains the output we see in the console. You may be wondering why you ever would want a block of work to be executed synchronously. Isn't the benefit of using Grand Central Dispatch that work can be dispatched to a background thread for asynchronous execution?
That is true, but it can be useful in some scenarios. Let me give you an example. The sync execute: method is useful to serialize state between subsystems. To understand what that means, you first need to become familiar with mutual exclusion. What is mutual exclusion and why is it important? Grand Central Dispatch makes it easy to take advantage of the capabilities of a modern device. You don't need to worry about threads or the resources that are available.
Queues also have different qos Quality of Service which sets the task performing priority from highest to lowest here :. There is also. If it wasn't possible to detect the qos the qos will be used between.
Synchronous function returns control to the current queue only after the task is finished. It blocks the queue and waits until the task is finished. Asynchronous function returns control to the current queue right after task has been sent to be performed on the different queue. It doesn't wait until the task is finished.
It doesn't block the queue. The most popular mistakes programmers make while projecting the concurrent apps are the following:. NEVER call the sync function on the main queue. If you call the sync function on the main queue it will block the queue as well as the queue will be waiting for the task to be completed but the task will never be finished since it will not be even able to start due to the queue is already blocked.
It is called deadlock.
0コメント